📂题解
🔖dp
2024-08-04 08:22阅读: 25评论: 0推荐: 0

ABC365D 题解

赛时脑抽了没写出来。赛后一听说是 DP 就秒了 /wul

为方便,我们用数字代替字母,用 1 表示石头(R),2 表示剪刀(S),3 表示布(P)。同时定义函数 ne(j)=jmod3+1,则有 ne(a)=b a 能赢过出 b

定义一下状态。用 fi,j(1j3) 表示“考虑前 i 位,且当第 i 位出 石头/剪刀/布 时赢得的最多场次“。

我们发现用上述状态可以很轻易地转移。我们可以通过前一位出的与当前出的不同的两种状态转移之。

有:

fi,j=max{fi1,ne(j),fi1,ne(ne(j))}+[ne(j)=si]

然后就做完了。记得先将 s 数组的字母转成数字。时间复杂度 O(n)

#include <iostream>  
#include <cstdio>  
#include <map>  
using namespace std;  
  
#define int long long  
const int N = 200010;  
int n, f[N][5]; string s;  
map<charint> mp;  
int ne(int x) {return x % 3 + 1;}  
  
  
signed main() {  
    cin >> n >> s; s = ' ' + s;  
    mp['R'] = 1, mp['S'] = 2, mp['P'] = 3;  
    for (int i = 1; i <= n; i++) {  
        for (int j = 1; j <= 3; j++) {  
            if(ne(mp[s[i]]) == j) continue;  
            f[i][j] = max(f[i - 1][ne(j)], f[i - 1][ne(ne(j))]);  
            if(ne(j) == mp[s[i]]) f[i][j]++;  
        }  
    }  
    int ans = 0;  
    for (int j = 1; j <= 3; j++) ans = max(ans, f[n][j]);  
    cout << ans;  
    return 0;  
}

本文作者:Running-a-way

本文链接:https://www.cnblogs.com/Running-a-way/p/18341433

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Running_a_way  阅读(25)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起