[洛谷]P3609 [USACO17JAN]Hoof, Paper, Scissor (#记忆化搜索)

75 篇文章 0 订阅
36 篇文章 0 订阅

题目背景

欢迎提供翻译,请直接在讨论区发帖,感谢你的贡献。

题目描述

You have probably heard of the game "Rock, Paper, Scissors". The cows like to play a similar game they call "Hoof, Paper, Scissors".

The rules of "Hoof, Paper, Scissors" are simple. Two cows play against each-other. They both count to three and then each simultaneously makes a gesture that represents either a hoof, a piece of paper, or a pair of scissors. Hoof beats scissors (since a hoof can smash a pair of scissors), scissors beats paper (since scissors can cut paper), and paper beats hoof (since the hoof can get a papercut). For example, if the first cow makes a "hoof" gesture and the second a "paper" gesture, then the second cow wins. Of course, it is also possible to tie, if both cows make the same gesture.

Farmer John wants to play against his prize cow, Bessie, at NN games of "Hoof, Paper, Scissors" (1 \leq N \leq 100,0001≤N≤100,000). Bessie, being an expert at the game, can predict each of FJ's gestures before he makes it. Unfortunately, Bessie, being a cow, is also very lazy. As a result, she tends to play the same gesture multiple times in a row. In fact, she is only willing to switch gestures at most KK times over the entire set of games (0 \leq K \leq 200≤K≤20). For example, if K=2K=2, she might play "hoof" for the first few games, then switch to "paper" for a while, then finish the remaining games playing "hoof".

Given the sequence of gestures FJ will be playing, please determine the maximum number of games that Bessie can win.

你可能听说过“石头,剪刀,布”的游戏。FJ的牛喜欢玩一个类似的游戏,它们称之为“蹄子,剪刀,布”(“蹄子”就是“石头”)。

游戏规则很简单:比赛双方同时数到3,然后同时出一个手势,代表“蹄子”“剪刀”或“布”。“蹄子”胜“剪刀”,“剪刀”胜“布”,“布”胜“蹄子”。举个例子,第一头牛出“蹄子”,第二头牛出“布”,则第二头牛胜利。当然,也可以“平局”(如果两头牛手势相同的话)。

FJ想对阵自己获奖的牛,贝西。贝西作为一个专家,能够预测FJ的手势。不幸的是,贝西作为一头牛,也十分的懒惰。事实上,她只愿意变换固定次数的手势来完成游戏。例如,她可能只想变1次,则他可能出“蹄子”几次,剩下的都出“布”。

鉴于贝西预测FJ会出的手势,以及她想变的次数,求出她最多能赢多少场

输入输出格式

输入格式:

The first line of the input file contains NN and KK.

The remaining NN lines contains FJ's gestures, each either H, P, or S.

输出格式:

Print the maximum number of games Bessie can win, given that she can only change gestures at most KKtimes.

输入输出样例

输入样例#1

5 1
P
P
H
P
S

输出样例#1

4

思路

硬核记搜。

#include <stdio.h>
#include <iostream>
using namespace std;
int n,k,a[100011],dp[100011][22][4],s;
char c;
int dfs(int i,int chance,int times)//i是FJ出的第i个手势,也可以转换为第i轮;chance是机会,times是FJ当前的手势种类 
{
	if(i>n || chance>k) return 0;//结束/机会用完都要返回 
	if(dp[i][chance][times]!=0)//记忆化 
	{
		return dp[i][chance][times];
	}
	if(chance==k)//如果还有机会,也就是最后一次机会,奶牛就不能变换手势了 
	{
		if(times==1 && a[i]==2)//剪刀赢布,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=dfs(i+1,chance,1)+1;
		}
		else if(times==2 && a[i]==3)//布赢石头,可以变换当前的手势也可以不变换 
		{
			dp[i][chance][times]=dfs(i+1,chance,2)+1;
		}
		else if(times==3 && a[i]==1)//石头赢剪刀,可以变换当前的手势也可以不变换 
		{
			dp[i][chance][times]=dfs(i+1,chance,3)+1;
		}
		if(times==1 && a[i]!=2)//剪刀没有赢布,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=dfs(i+1,chance,1);
		}
		else if(times==2 && a[i]!=3)//布没有石头,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=dfs(i+1,chance,2);
		}
		else if(times==3 && a[i]!=1)//石头没有赢剪刀,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=dfs(i+1,chance,3);
		}
	}
	else
	{
		if(times==1 && a[i]==2)//剪刀赢布,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=max(max(dfs(i+1,chance,1)+1,dfs(i+1,chance+1,2)+1),dfs(i+1,chance+1,3)+1);
		}
		else if(times==2 && a[i]==3)//布赢石头,可以变换当前的手势也可以不变换 
		{
			dp[i][chance][times]=max(max(dfs(i+1,chance+1,1)+1,dfs(i+1,chance,2)+1),dfs(i+1,chance+1,3)+1);
		}
		else if(times==3 && a[i]==1)//石头赢剪刀,可以变换当前的手势也可以不变换 
		{
			dp[i][chance][times]=max(max(dfs(i+1,chance+1,1)+1,dfs(i+1,chance+1,2)+1),dfs(i+1,chance,3)+1);
		}
		if(times==1 && a[i]!=2)//剪刀没有赢布,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=max(max(dfs(i+1,chance,1),dfs(i+1,chance+1,2)),dfs(i+1,chance+1,3));
		}
		else if(times==2 && a[i]!=3)//布没有石头,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=max(max(dfs(i+1,chance+1,1),dfs(i+1,chance,2)),dfs(i+1,chance+1,3));
		}
		else if(times==3 && a[i]!=1)//石头没有赢剪刀,可以变换当前的手势也可以不变换
		{
			dp[i][chance][times]=max(max(dfs(i+1,chance+1,1),dfs(i+1,chance+1,2)),dfs(i+1,chance,3));
		}
	}
	return dp[i][chance][times];
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	register int i,j;
	cin>>n>>k;
	for(i=1;i<=n;i++)
	{
		cin>>c;
		if(c=='P') a[i]=1;//令1是剪刀 
		if(c=='H') a[i]=2;//2是布 
		if(c=='S') a[i]=3;//3是石头 
	}
	cout<<max(max(dfs(1,0,1),dfs(1,0,2)),dfs(1,0,3))<<endl;//罗列3种情况 
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值