首页 > 其他 > 详细

[bzoj1806] [ioi2007]Miners 矿工配餐

时间:2016-02-10 23:21:30      阅读:560      评论:0      收藏:0      [点我收藏+]

  相当于noip前两题难度的ioi题。。。。。。。。

  还是挺好想的。。。算是状压一下?。。。两个二进制位可以表示三种食物或者没有,所以用四个二进制位表示某个煤矿最近两餐的情况。。。

  先把各种情况加上各种食物后的产出与新情况预处理出来吧。(如果两餐分别开两维的话似乎不太好预处理)

  f[i][j][k]表示前i辆车,两个煤矿最近两餐情况分别为j和k时的最大产出。i那维滚动一下

  感觉要注意的就是,两餐的情况是有非法情况的(前一餐吃了,后一餐不吃);还有就是有的情况可能用目前的食物凑不出来。。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 const int inf=1000233333;
 6 int f[2][16][16],v[16][4],turn[16][4],num1[16];
 7 int mp[16],kind;
 8 int i,j,k,n,m,x,now,pre,ans;
 9 char rx;
10 
11 inline int max(int a,int b){return a<b?b:a;}
12 
13 int main(){
14     register int j,k;
15     for(i=0;i<16;num1[i]=(i>3)+((i&3)>0),i++)if(!(i>3&&!(i&3))){
16         mp[++kind]=i;
17         for(j=1;j<4;j++){
18             int x1=i>>2,x2=i&3;
19             v[i][j]=(j!=x1&&j!=x2)+(x1||x2)+(x1&&x2&&x1!=x2);
20             turn[i][j]=(x2<<2)|j;
21 
22         }
23     }
24     scanf("%d",&n);
25     memset(f[0],150,sizeof(f[0])),f[0][0][0]=0;
26     for(i=now=1,pre=0;i<=n;i++,swap(now,pre)){
27         memset(f[now],150,sizeof(f[now]));
28         for(rx=getchar();rx<A||rx>Z;rx=getchar());
29         if(rx==M)x=1;else x=rx==F?2:3;
30         for(j=1;j<=kind;j++)for(k=1;k<=kind;k++)
31             f[now][turn[mp[j]][x]][mp[k]]=max(f[now][turn[mp[j]][x]][mp[k]],f[pre][mp[j]][mp[k]]+v[mp[j]][x]),
32             f[now][mp[j]][turn[mp[k]][x]]=max(f[now][mp[j]][turn[mp[k]][x]],f[pre][mp[j]][mp[k]]+v[mp[k]][x]);
33     }
34     for(j=1;j<=kind;j++)for(k=1;k<=kind;k++)ans=max(ans,f[pre][mp[j]][mp[k]]);
35     printf("%d\n",ans);
36     return 0;
37 }
View Code

 

[bzoj1806] [ioi2007]Miners 矿工配餐

原文:http://www.cnblogs.com/czllgzmzl/p/5186160.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!