标签: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