标签:highlight min main 题解 允许 滚动数组 需要 任务 字母
题解:直接用f[i][a][b][c][d]表示前i个食品车,1号矿的上一份是a,上上份是b,2号矿的上一份是c,上上份是d,的最大产量。因为卡内存,所以滚动数组即可。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int n,ans; int f[2][4][4][4][4]; char str[100010]; int calc(int x,int a,int b) { if(!a) return 1; if(!b) return 1+(x!=a); return 1+(x!=a||x!=b)+(x!=a&&x!=b&&a!=b); } int main() { scanf("%d%s",&n,str+1); int i,j,x,a,b,c,d; memset(f,0x80,sizeof(f)); f[0][0][0][0][0]=0; for(i=1;i<=n;i++) { j=i&1; memset(f[j],0x80,sizeof(f[j])); if(str[i]==‘M‘) x=1; if(str[i]==‘F‘) x=2; if(str[i]==‘B‘) x=3; for(a=0;a<=3;a++) for(b=0;b<=3;b++) for(c=0;c<=3;c++) for(d=0;d<=3;d++) { f[j][x][a][c][d]=max(f[j][x][a][c][d],f[j^1][a][b][c][d]+calc(x,a,b)); f[j][a][b][x][c]=max(f[j][a][b][x][c],f[j^1][a][b][c][d]+calc(x,c,d)); } } for(a=0;a<=3;a++) for(b=0;b<=3;b++) for(c=0;c<=3;c++) for(d=0;d<=3;d++) ans=max(ans,f[n&1][a][b][c][d]); printf("%d",ans); return 0; }
【BZOJ1806】[Ioi2007]Miners 矿工配餐 DP
标签:highlight min main 题解 允许 滚动数组 需要 任务 字母
原文地址:http://www.cnblogs.com/CQzhangyu/p/7605540.html