本文章为原创文章,未经过允许不得转载
运行要求
运行时间限制: 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次的出拳不能一样

首先我们要看,要想拿高分,也要考虑在每次出拳的时候要赢
名称未設定.001.jpeg
我们可能会这么样,就算i次赢了,但是第i+K次就不能出拳了,那么会不会存在故意在第i次输掉,然后第i+K次赢下,反而可以拿到更高的积分呢?

答案是:不会

能赢的先赢下来!

首先K存在,只会影响i,i+k都出同一种拳获胜的情况
名称未設定.002.jpeg
如图所示K=3的情况下i=2,i=5都需要通过出石头获胜的情况下,i=2,i=5只能赢一局。

然后K存在,不会会影响i,i+k都出不同种拳获胜的情况
名称未設定.003.jpeg
如图所示K=3的情况下i=2,i=5分别需要通过出石头和剪刀获胜的情况下,i=2,i=5都可以赢下来。

我们把先赢的都赢下来,再把被K限制的不能赢的输掉
比如i和i+k都可以用石头赢
把i先赢下来,i+k选择用剩下的剪刀或者石头。但是具体用哪个取决于i+2*k了
名称未設定.004.jpeg
如图所示,K=3
第1次想赢的话得出石头,第4次想赢的话也得出石头,但是第1次出了石头,第4次只能出剪刀或者布
但是为了让第7次能够出布赢,第4次要选择出剪刀,而不是出布

所以我们干脆这样做
遍历字符串T,算出要赢的话需要出什么

每遍历到第i个元素的时候,去check以下i-k的元素的出拳。如果第i个元素的出拳和第i-k的元素的出拳一样,那么我们干脆把第i-k的元素的出拳设为“”。
因为反正拿不了分
但是为了让i+2k拿分,还是得看i+2k的出拳的,但是求出来对于结果没有帮助,我们就用“”代替

名称未設定.005.jpeg
如图所示,第4次出布或者石头已经不重要了,用“”字符串代替。
代表第4次不拿分,且不影响第7次拿分

再解释一下为什么要能赢下的先赢下来。
名称未設定.006.jpeg
如图所示,K=3
我们先把i=1先赢下来
i=4设为空字符串,不拿分,这样i=7需要出石头赢下来的话,也可以出石头

但是如果i=1先不赢下来的话
名称未設定.007.jpeg
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的冲突

这道理还有动态规划的解法,研究好了后继续补上

※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
二维码.jpg



伟大不DIAO
1 声望1 粉丝

Done is better than perfect