本文章为原创文章,未经过允许不得转载
运行要求
运行时间限制: 2sec
内存限制: 1024MB
原题链接
题目
小明在游戏中心玩石头剪刀布的游戏。游戏规则如下。
- 小明和石头剪刀布游戏机进行N次石头剪刀布游戏。如果打平也算一局
-
小明和游戏机的角逐中赢得游戏的话,那么按照游戏机的出拳,可以按照如下方式获得积分。
- 小明出石头赢得游戏,获取R点积分
- 小明出剪刀赢得游戏,获取S点积分
- 小明出布赢得游戏,获取P点积分
- 但是有一个条件,小明的出拳和小明K回以前的出拳不能相同。(第K回出拳的方式可以任意)
石头剪刀布的游戏机在比赛开始以前就决定好了游戏机的出拳顺序。超能力者小明在游戏前就读取了游戏机的出拳顺序信息。
小明获得的游戏机的出拳顺序信息是一串字符T
T的第i(1<=i<=N)个字符是'r'的话,代表游戏机第i回出拳“石头”
T的第i(1<=i<=N)个字符是's'的话,代表游戏机第i回出拳“剪刀”
T的第i(1<=i<=N)个字符是'p'的话,代表游戏机第i回出拳“布”
小明和游戏机进行了N次石头剪刀布的游戏,游戏结束的时候,小明获得的最大的点数是多少?
输入前提条件
- 2<=N<=10^5
- 1<=K<=N-1
- 1<=R,S,P<=10^4
- N,K,R,S,P全部为整数
- |T| = N (字符串T的长度为N)
- T由'r','s','p'构成
输入
N K
R S P
T
输出
输出最大的得分的值
例1
输入
5 2
8 7 6
rsrpr
输出
21
游戏机的出拳顺序是
石头,剪刀,石头,布,石头
小明根据以上信息进行下面的出拳
布,石头,石头,剪刀,布
总共获得27点
再高就获取不了了,最后输出27
例2
输入
7 1
100 10 1
ssssppr
输出
211
例3
输入
30 5
325 234 123
rspsspspsrpspsppprpsprpssprpsr
输出
4996
读懂题目
石头剪刀布的游戏规则中国和日本都一样,也不知道是哪个抄哪个的。
反正每次赢的方法有3中
出石头赢
出布赢
出剪刀赢
每种赢法获取的积分也不一样
出石头赢 R分
出布赢 P分
出剪刀赢 S分
还有就是
有一个K值
比如说K为3的话
那么第3次的出拳方法和第1次不能一样
第5次的出拳方法和第2次的出拳方法 不能一样
解题思路
这题卡住我们的是K
也就是说第i次出拳和第i-K次的出拳不能一样
首先我们要看,要想拿高分,也要考虑在每次出拳的时候要赢
我们可能会这么样,就算i次赢了,但是第i+K次就不能出拳了,那么会不会存在故意在第i次输掉,然后第i+K次赢下,反而可以拿到更高的积分呢?
答案是:不会
能赢的先赢下来!
首先K存在,只会影响i,i+k都出同一种拳获胜的情况
如图所示K=3的情况下i=2,i=5都需要通过出石头获胜的情况下,i=2,i=5只能赢一局。
然后K存在,不会会影响i,i+k都出不同种拳获胜的情况
如图所示K=3的情况下i=2,i=5分别需要通过出石头和剪刀获胜的情况下,i=2,i=5都可以赢下来。
我们把先赢的都赢下来,再把被K限制的不能赢的输掉
比如i和i+k都可以用石头赢
把i先赢下来,i+k选择用剩下的剪刀或者石头。但是具体用哪个取决于i+2*k了
如图所示,K=3
第1次想赢的话得出石头,第4次想赢的话也得出石头,但是第1次出了石头,第4次只能出剪刀或者布
但是为了让第7次能够出布赢,第4次要选择出剪刀,而不是出布
所以我们干脆这样做
遍历字符串T,算出要赢的话需要出什么
每遍历到第i个元素的时候,去check以下i-k的元素的出拳。如果第i个元素的出拳和第i-k的元素的出拳一样,那么我们干脆把第i-k的元素的出拳设为“”。
因为反正拿不了分
但是为了让i+2k拿分,还是得看i+2k的出拳的,但是求出来对于结果没有帮助,我们就用“”代替
如图所示,第4次出布或者石头已经不重要了,用“”字符串代替。
代表第4次不拿分,且不影响第7次拿分
再解释一下为什么要能赢下的先赢下来。
如图所示,K=3
我们先把i=1先赢下来
i=4设为空字符串,不拿分,这样i=7需要出石头赢下来的话,也可以出石头
但是如果i=1先不赢下来的话
i=4赢下来,i=7的话就赢不下来了,这样本来可以在i=1,4,7中赢2局的,只赢了1局。
代码
N,K = map(int,input().split())
R,S,P = map(int,input().split())
T = list(input())
def calculate(n,k,r,s,p,trr):
points = []
total = 0
for i in range(n):
t = trr[i]
score = 0
if t == 'r':
point = "p"
score = p
if t == "s":
point = "r"
score = r
if t == "p":
point = "s"
score = s
if i - k >= 0:
if point == points[i - k]:
point = ""
score = 0
total = total + score
points.append(point)
print(total)
calculate(N,K,R,S,P,T)
总结
这道理考察了对K的理解。K的影响范围实际上只有(i,i+K)对于(i,i+2k)可以通过对i+K的调整避免i和i+2k的冲突
这道理还有动态规划的解法,研究好了后继续补上
※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。