zoukankan      html  css  js  c++  java
  • 【动态规划/递推】BZOJ1806[IOI2007]- Miners

    IOI历史上的著名水题,我这种蒟蒻都能写的东西。

    【思路】

    用1、2、3分别代替三种食物,0表示当前矿井没有食物。f[i][a][b][c][d]当前第i个食物,矿1的食物顺序由上至下为a,b;矿2的食物顺序由上至下为c,d。 

    判断产物数量的方法很巧妙,由下至上a,b,c。初始时默认投入一个食物至少生产一单位,如果a为有食物且与bc不同,则加一单位;如果b为有食物且与c不同,再加一个单位。最后加一个滚动数组就可以了。

    【错因】

    1.因为a,b,c,d大小范围是0..3,但是我把下标范围写3!一定要写4!我就是一不小心写错了,居然改了两个晚上,完全没有考虑到错因在这里....

    2.还有初始化的时候只有f[0][0][0][0][0]是0,不要把所有第一位是0的都写成0了..

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAXN=100000+500;
     6 int n;
     7 int food[MAXN];
     8 int f[2][4][4][4][4];//f[i][a][b][c][d]当前第i个食物,矿1的食物顺序由上至下为a,b;矿2的食物顺序由上至下为c,d。 
     9 
    10 int compare(int x,int y,int z)
    11 {
    12     int t=1;
    13     if (x!=0 && x!=y && x!=z) t++;
    14     if (y!=0 && y!=z) t++;
    15     return t;
    16 }
    17 
    18 int main()
    19 {
    20     scanf("%d",&n);
    21     getchar();
    22     for (int i=0;i<n;i++)
    23     {
    24         char c;
    25         scanf("%c",&c);
    26         if (c=='M') food[i]=1;
    27         if (c=='F') food[i]=2;
    28         if (c=='B') food[i]=3;
    29     }
    30     
    31     memset(f,-1,sizeof(f));
    32     f[0][0][0][0][0]=0;33     int ans=-1;
    34     for (int i=0;i<n;i++)
    35         for (int a=0;a<=3;a++)
    36             for (int b=0;b<=3;b++)
    37                 for (int c=0;c<=3;c++)
    38                     for (int d=0;d<=3;d++)
    39                     {
    40                         if (f[i%2][a][b][c][d]==-1) continue;
    41                         int add1=compare(b,a,food[i]),add2=compare(d,c,food[i]);
    42                         
    43                         int x=food[i];
    44                         f[(i+1)%2][x][a][c][d]=max(f[(i+1)%2][x][a][c][d],f[i%2][a][b][c][d]+add1);
    45                         f[(i+1)%2][a][b][x][c]=max(f[(i+1)%2][a][b][x][c],f[i%2][a][b][c][d]+add2);
    46                         if ((i==n-1) && (f[(i+1)%2][x][a][c][d]>ans)) ans=f[(i+1)%2][x][a][c][d];
    47                         if ((i==n-1) && (f[(i+1)%2][a][b][x][c]>ans)) ans=f[(i+1)%2][a][b][x][c];
    48                     }
    49     cout<<ans<<endl;
    50     return 0;
    51 }
  • 相关阅读:
    20201231《信息安全专业导论》第一周学习总结
    Python模拟进程状态
    Python gui
    2020-2021-1 20201208《信息安全专业导论》第10周学习总结
    2020-2021-1 20201208 《信息安全专业导论》第九周学习总结
    熟悉编程语言
    俄罗斯方块
    小学四则运算编程实践
    2020-2021-1-1 《信息安全专业导论》第八周学习总结
    2020-2021-1 20201208 《信息安全专业导论》第七周学习总结
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/4796368.html
Copyright © 2011-2022 走看看