令fi,a1,a2,b1,b2表示当前是第i辆餐车,第一个煤矿的倒数两个是
不要忘记处理前面不足3个即a1,a2,b1,b2可能为0的情况!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100005
using namespace std;
int n,ans;
char s[N];
int a[N];
int f[4][4][4][4][4];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline int calc(int a,int b,int c)
{
int tmp=1;
if (a!=0&&a!=b&&a!=c) tmp++;
if (b!=0&&b!=c) tmp++;
return tmp;
}
int main()
{
n=read();
memset(f,-1,sizeof(f));
f[1][0][0][0][0]=0;
scanf("%s",s+1);
for (int i=1;i<=n;i++)
if (s[i]=='M') a[i]=1;
else if (s[i]=='B') a[i]=2;
else if (s[i]=='F') a[i]=3;
for (int i=1;i<=n;i++)
for (int a1=0;a1<=3;a1++)
for (int a2=0;a2<=3;a2++)
for (int b1=0;b1<=3;b1++)
for (int b2=0;b2<=3;b2++)
{
int x=i%4,y=(i+1)%4;
if (f[x][a1][a2][b1][b2]==-1) continue;
int tmp;
tmp=calc(a1,a2,a[i]);
f[y][a2][a[i]][b1][b2]=max(f[y][a2][a[i]][b1][b2],f[x][a1][a2][b1][b2]+tmp);
tmp=calc(b1,b2,a[i]);
f[y][a1][a2][b2][a[i]]=max(f[y][a1][a2][b2][a[i]],f[x][a1][a2][b1][b2]+tmp);
}
for (int a1=0;a1<=3;a1++)
for (int a2=0;a2<=3;a2++)
for (int b1=0;b1<=3;b1++)
for (int b2=0;b2<=3;b2++)
ans=max(ans,f[(n+1)%4][a1][a2][b1][b2]);
cout << ans << endl;
}
135

被折叠的 条评论
为什么被折叠?



