Hoof, Paper, Scissors - UPCOJ 3426 - 三维动态规划DP

140 篇文章 0 订阅
91 篇文章 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 N games of “Hoof, Paper, Scissors” (1≤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 K times over the entire set of games (0≤K≤20). For example, if K=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.

输入

  The first line of the input file contains N and K.
  The remaining N 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 K times.

样例输入

5 1
P
P
H
P
S

样例输出

4


题意:

  比n局石头剪子布,有k次变换的机会,可以变可以不变,假如出石头的话,k=0就会一直出石头直到游戏结束。


思路:

  先根据k=0``n=0更新出第一层关系,然后再层层覆盖不断更新出所有情况下的得分。


实现:

#include <bits/stdc++.h>
using namespace std;
#define maxn 100007
int a[maxn],dp[maxn][57][3],n,k_,win[3][3];
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    ios_base::sync_with_stdio(false);cin.tie(0);
    char c;
    win[1][2] = win[2][0] = win[0][1] = 1;
    while(memset(a,0,sizeof a), memset(dp,0,sizeof dp),cin >> n >> k_) {
        for(int i=1 ; i<=n ; i++) cin >> c, a[i] = c == 'H' ? 0 : c == 'P' ? 2 : 1;
        for(int i=1 ; i<=n ; i++)
            for(int j=0 ; j<3 ; j++)
                dp[i][0][j] = dp[i-1][0][j] + win[j][a[i]];
        for(int k=1 ; k<=k_ ; k++) {
            for(int i=1 ; i<=n ; i++) {
                for(int j=0 ; j<3 ; j++) {
                    dp[i][k][j] = max(dp[i-1][k][j],
                                      max(dp[i-1][k-1][(j+1)%3], dp[i-1][k-1][(j+2)%3])) + win[j][a[i]];
                }
            }
        }
        int result = -1;
        for(int i=0 ; i<3 ; i++) result = max(result, dp[n][k_][i]);
        cout << result << '\n';
    }
    return 0;
}

其他:

  值得注意的是,有关游戏局数n的那一层循环可以被省略,也就是说三维DP可以压缩为二维DP,通过使用循环数组来实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值