#include <stdio.h>
int main()
{
puts("转载请注明出处谢谢");
puts("http://blog.csdn.net/vmurder/article/details/42969559");
}
题解:f[i][j][k][l][m]表示到第i个字母,第一坑的当前两个字母是jk,第二坑lm时的最大权值。
然后暴力瞎转移就好了。
对了,10W*4*4*4*4=2560W,64M内存限制,要写滚动数组。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 101000
#define inf 0x3f3f3f3f
using namespace std;
char s[N];
int f[2][4][4][4][4],n;
int now,last;
int main()
{
freopen("test.in","r",stdin);
int i,j,k,l,m;
int a,b,alp;
scanf("%d",&n);
scanf("%s",s+1);
now=1,last=0;
memset(f[now],0xef,sizeof f[now]);
f[now][0][0][0][0]=0;
for(i=1;i<=n;i++)
{
if(s[i]=='M')alp=1;
if(s[i]=='F')alp=2;
if(s[i]=='B')alp=3;
now^=1,last^=1;
memset(f[now],0xef,sizeof f[now]);
for(j=0;j<4;j++)
{
for(k=0;k<4;k++)
{
a=1;
if(j)a++;
if(k)a++;
if(j==k&&j)a--;
if(alp==j)a--;
if(alp==k&&j!=k)a--;
for(l=0;l<4;l++)
{
for(m=0;m<4;m++)
{
b=1;
if(l)b++;
if(m)b++;
if(l==m&&l)b--;
if(alp==l)b--;
if(alp==m&&l!=m)b--;
//分配给矿坑1
f[now][k][alp][l][m]=max(f[now][k][alp][l][m],f[last][j][k][l][m]+a);
//分配给矿坑2
f[now][j][k][m][alp]=max(f[now][j][k][m][alp],f[last][j][k][l][m]+b);
}
}
}
}
}
int ans=0;
for(i=0;i<4;i++)for(j=0;j<4;j++)for(k=0;k<4;k++)for(l=0;l<4;l++)ans=max(ans,f[now][i][j][k][l]);
printf("%d\n",ans);
}