题目大意
有两个矿井及N辆矿车,每个矿工的产煤量与其最后三顿饭的种类数有关。求最大产煤量。
算法
DP,f[i][j1][j2][j3][j4][j5]表示处理到第i辆,第一个矿井前两天吃的是j1,j2,第二个矿井前两天吃的是j3,j4。
但是空间只有18MB,所以我们采用滚动数组
代码
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
#define max(a,b) ((a)>(b))?(a):(b)
#define min(a,b) ((a)<(b))?(a):(b)
#define _f(i,a,b) for(int i=a;i<=b;i++)
unsigned char f[100001]={0};
int x[4][4][4][4],y[4][4][4][4];
int main(){
int n;
scanf("%d\n",&n);
for(int i=1;i<=n;i++){
char ch=getchar();
switch(ch){
case 'M':
f[i]++;
case 'F':
f[i]++;
case 'B':
f[i]++;
}
}
memset(x,0,sizeof(x));
for(int i=n;i>=1;i--){
memset(y,0,sizeof(y));
_f(j1,0,3)_f(j2,0,3)_f(j3,0,3)_f(j4,0,3){
if((j1 && !j2)||(j3 && !j4))
continue;
int _1,_2;
if((!j1 && !j2)||(!j1 && j2==f[i])||
(j1==j2 && j2==f[i]))
_1=1;
else if(j1!=j2 && j2!=f[i] && j1!=f[i] && j1 && j2)
_1=3;
else
_1=2;
if((!j3 && !j4)||(!j3 && j4==f[i])||
(j3==j4 && j4==f[i]))
_2=1;
else if(j3!=j4 && j4!=f[i] && j3!=f[i] && j3 && j4)
_2=3;
else
_2=2;
y[j1][j2][j3][j4]=max(x[j2][f[i]][j3][j4]+_1,
x[j1][j2][j4][f[i]]+_2);
}
swap(x,y);
}
printf("%d\n",x[0][0][0][0]);
return 0;
} 
京公网安备 11010502036488号