题目背景
本题与 银组同名题目 在题意上一致,唯一的差别在于对变手势次数的限制。
题目描述
你可能玩过“石头,剪刀,布”,这个游戏在奶牛中同样流行,不过它的名字变成了“蹄子,剪刀,布”。
“蹄子,剪刀,布”和“石头,剪刀,布”的规则十分类似,两只奶牛数到三,然后出一个代表蹄子,剪刀或布的手势。蹄子胜过剪刀,剪刀胜过布,布胜过蹄子。特别地,如果两只奶牛的手势相同,则视为平局。
现在 FJ 和 Bassie 要进行 N 轮对抗。Bassie 已经预测了 FJ 每一轮要出的手势。然而 Bassie 很懒,她最多只想变换 K 次手势。
现在请你帮 Bassie 求出她最多能赢多少轮。
输入格式
第一行输入两个整数 N,K(1≤N≤10^5,0≤K≤20)。
接下来 N 行,每行一个字母,代表 FJ 这一轮出的手势。H
代表蹄子(Hoof),S
代表剪刀(Scissors),P
代表布(Paper)。
输出格式
输出一个整数,代表 Bassie 在最多变换 K 次手势的前提下最多赢多少轮。
输入输出样例
输入 #1
5 1 P P H P S
输出 #1
4
很简单的模拟(中间还有记忆化)
#include<bits/stdc++.h>
using namespace std;
int n,k,dp[5][100001][25],f[303030];
char s;
inline int dfs(int num,int chance,int pos){
if(pos>n||chance>k) return 0;
if(chance>k) return -0x3FFFFFFF;
if(dp[num][pos][chance]!=0) return dp[num][pos][chance];
if(chance==k){//机会用完了
if(num==1&&f[pos]==2) dp[num][pos][chance]=dfs(1,chance,pos+1)+1;//剪刀赢了布,可以变换当前的手势,也可以不变换
else if(num==2&&f[pos]==3) dp[num][pos][chance]=dfs(2,chance,pos+1)+1;//布赢了石头,可以变换当前的手势,也可以不变换
else if(num==3&&f[pos]==1) dp[num][pos][chance]=dfs(3,chance,pos+1)+1;//石头赢了剪刀,可以变换当前的手势,也可以不变换
if(num==1&&f[pos]!=2) dp[num][pos][chance]=dfs(1,chance,pos+1);//剪刀没有赢布,可以变换当前的手势,也可以不变换
else if(num==2&&f[pos]!=3) dp[num][pos][chance]=dfs(2,chance,pos+1);//布没有赢石头,可以变换当前的手势,也可以不变换
else if(num==3&&f[pos]!=1) dp[num][pos][chance]=dfs(3,chance,pos+1);//石头没有赢剪刀,可以变换当前的手势,也可以不变换
}
else{//机会没用完
if(num==1&&f[pos]==2) dp[num][pos][chance]=max(max(dfs(1,chance,pos+1)+1,dfs(2,chance+1,pos+1)+1),dfs(3,chance+1,pos+1)+1);//剪刀赢了布,可以变换当前的手势,也可以不变换
else if(num==2&&f[pos]==3) dp[num][pos][chance]=max(max(dfs(1,chance+1,pos+1)+1,dfs(2,chance,pos+1)+1),dfs(3,chance+1,pos+1)+1);//布赢了石头,可以变换当前的手势,也可以不变换
else if(num==3&&f[pos]==1) dp[num][pos][chance]=max(max(dfs(1,chance+1,pos+1)+1,dfs(2,chance+1,pos+1)+1),dfs(3,chance,pos+1)+1);//石头赢了剪刀,可以变换当前的手势,也可以不变换
if(num==1&&f[pos]!=2) dp[num][pos][chance]=max(max(dfs(1,chance,pos+1),dfs(2,chance+1,pos+1)),dfs(3,chance+1,pos+1));//剪刀没有赢布,可以变换当前的手势,也可以不变换
else if(num==2&&f[pos]!=3) dp[num][pos][chance]=max(max(dfs(1,chance+1,pos+1),dfs(2,chance,pos+1)),dfs(3,chance+1,pos+1));//布没有赢石头,可以变换当前的手势,也可以不变换
else if(num==3&&f[pos]!=1) dp[num][pos][chance]=max(max(dfs(1,chance+1,pos+1),dfs(2,chance+1,pos+1)),dfs(3,chance,pos+1));//石头没有赢剪刀,可以变换当前的手势,也可以不变换
}
return dp[num][pos][chance];
}
int main(){
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>s;
if(s=='P') f[i]=1;
if(s=='H') f[i]=2;
if(s=='S') f[i]=3;
}
cout<<max(max(dfs(1,0,1),dfs(2,0,1)),dfs(3,0,1));//模拟,一开始出剪刀||石头||布的情况
return 0;
}
温馨提示:记得开氧气优化欧