题意:你和小
一道线性 DP。
我们设
初始化把
然后就可以开始递推了,分别处理
最后答案即为
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define INF 1e9;
using namespace std;
const int maxn=100011,maxk=21;
int n,k,f[maxn][maxk][3],num[maxn];//0石头1剪刀2布
char c;
int compete(int a,int b)
{
if(a==0&&b==1)
return 1;
else if(a==1&&b==2)
return 1;
else if(a==2&&b==0)
return 1;
else
return 0;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("\n%c",&c);
if(c=='H')
num[i]=0;
else if(c=='S')
num[i]=1;
else
num[i]=2;
}
memset(f,-0x3f,sizeof(f));
f[0][0][0]=f[0][0][1]=f[0][0][2]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=2;j++)
f[i][0][j]=f[i-1][0][j]+compete(j,num[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
{
int x=compete(0,num[i]);
int y=compete(1,num[i]);
int z=compete(2,num[i]);
f[i][j][0]=max(max(f[i][j][0],f[i-1][j][0]+x),max(f[i-1][j-1][1]+x,f[i-1][j-1][2]+x));
f[i][j][1]=max(max(f[i][j][1],f[i-1][j][1]+y),max(f[i-1][j-1][0]+y,f[i-1][j-1][2]+y));
f[i][j][2]=max(max(f[i][j][2],f[i-1][j][2]+z),max(f[i-1][j-1][0]+z,f[i-1][j-1][1]+z));
/*for(int p=0;p<=2;p++)
printf("%d %d %d %d\n",i,j,p,f[i][j][p]);*/
}
printf("%d",max(max(f[n][k][0],f[n][k][1]),f[n][k][2]));
return 0;
}