zoukankan      html  css  js  c++  java
  • bzoj1609[Usaco2008 Feb]Eating Together麻烦的聚餐*

    bzoj1609[Usaco2008 Feb]Eating Together麻烦的聚餐

    题意:

    一个序列只由1﹑2﹑3三种数组成。求最少要改变多少个数使它变成不下降序列或不上升序列。序列大小≤30000

    题解:

    DP。设f[i][j]表示正在考虑第i个数,上一个数是j。求不下降序列最少改变个数方程:

    f[i][j]=min(f[i+1][k]+1,k∈[j,3]),a[i]<j
              min(f[i+1][a[i]],f[i+1][k]+1,k∈[j,3]且k!=a[i])a[i]>=j

    求不上升同理。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 50000
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define dec(i,j,k) for(int i=j;i>=k;i--)
     7 #define INF 0x3fffffff
     8 using namespace std;
     9 
    10 int n,a[maxn],x[5],y[5],ans;
    11 int main(){
    12     scanf("%d",&n); inc(i,1,n)scanf("%d",&a[i]); memset(x,0,sizeof(x));
    13     dec(i,n,1){
    14         memset(y,0,sizeof(y));
    15         inc(j,1,3)if(a[i]<j){
    16             y[j]=INF; inc(k,j,3)y[j]=min(y[j],x[k]+1);
    17         }else{
    18             y[j]=x[a[i]]; inc(k,j,3)if(k!=a[i])y[j]=min(y[j],x[k]+1);
    19         }
    20         swap(x,y);
    21     }
    22     ans=INF; inc(i,1,3)ans=min(ans,x[i]); memset(x,0,sizeof(x));
    23     dec(i,n,1){
    24         memset(y,0,sizeof(y));
    25         inc(j,1,3)if(a[i]>j){
    26             y[j]=INF; dec(k,j,1)y[j]=min(y[j],x[k]+1);
    27         }else{
    28             y[j]=x[a[i]]; dec(k,j,1)if(k!=a[i])y[j]=min(y[j],x[k]+1);
    29         }
    30         swap(x,y);
    31     }
    32     inc(i,1,3)ans=min(ans,x[i]); printf("%d",ans); return 0;
    33 }

    20160729

  • 相关阅读:
    关于以追加模式写入文件时,为什么第一行是空行?
    使用正则表达式的技巧
    super关键字的三种用法
    Excel快捷键
    重载与重写的区别
    方法重名
    区分子类方法中重名的三种变量
    继承
    Chapter08【String类、static、Arrays类、Math类】
    Math类
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5719866.html
Copyright © 2011-2022 走看看