题目大意:
一种游戏(类似于石头剪刀布):两个人分别给出一个字母,然后比较:H>S,S>P,P>H,我们已知对手的字母顺序,求在前n局中我们最多能赢多少次。
由于出字母的人非常懒,所以开局后会选定一种字母,中途只会改变k次,剩余状态下只会不停重复上一次出的字母,所以请你解决这个问题;
好吧,这道题就是DP题。
f[i][j][k]表示出到第i局,改变了j次,目前出的是第k个字母的最多赢的局数。
然后每次DP可以从f[i-1][j][k]和f[i-1][j-1][l(l!=k)]转移
然后就是统计f[n][k][0-2],取最大值即可
下面贴代码
#include<cstdio> #define max(a,b) ((a)>(b)?(a):(b)) using namespace std; int ds[100005]; char ch; int f[2][21][3]; int n,tot,ans; void swap(int &a,int &b){ int tmp; tmp=a;a=b;b=tmp; } int main(){ freopen("GP2.in","r",stdin); freopen("GP2.out","w",stdout); scanf("%d%d",&n,&tot); for(int i=1;i<=n;i++){ scanf("%s",&ch); if(ch==‘H‘)ds[i]=0; else if(ch==‘S‘)ds[i]=1; else ds[i]=2; } int pre=0,lst=1; for(int i=1;i<=n;i++) { for(int j=0;j<=tot;j++) for(int k=0;k<=2;k++) { for(int l=0;l<=2;l++) { if(k==l)f[lst][j][k]=max(f[lst][j][k],f[pre][j][l]); else if(j)f[lst][j][k]=max(f[lst][j][k],f[pre][j-1][l]); } f[lst][j][k]+=(ds[i]==(k+1)%3); } swap(pre,lst); } for(int i=0;i<=tot;i++) for(int j=0;j<=2;j++) ans=max(ans,f[pre][i][j]); printf("%d\n",ans); fclose(stdin); fclose(stdout); }
时间: 2024-10-10 12:05:00