abc365d有感

abc365d

$ Q$ & \(A\)

\(Q:这题暴力为何过不了?\)
\(A:qwq,因为每一个偶数长度的连续序列有两种应对方式qaq\)

那……那正解是啥……

搬出大招

\(\color{red}\mathbf{DP}\)!!!

状态?

\(f_{i,j}\) 表示前i个字符串这一位选择j这种方案的最大获胜数

转移?

还是看代码吧……

\(AC\) \(Code\)

点我查看
#include <bits/stdc++.h>

using namespace std;

int n;
int s[200010];
int f[200010][4];
int dp();

signed main() {
    cin >> n;for (int i = 1;i <= n;++i) { char ch;cin >> ch;if (ch == 'R')s[i] = 1;if (ch == 'S')s[i] = 2;if (ch == 'P')s[i] = 3; }//奇特的压行输入
    cout << dp() << "\n";//正式dp,声明在上面,函数在下面
}

int dp() {
    for (int i = 1;i <= n;++i) {
        for (int j = 1;j <= 3;++j) {
            if (s[i] == 1) {
                if (j == 1) {//石头->石头,会平局
                    f[i][j] = max(f[i - 1][2], f[i - 1][3]);
                }
                if (j == 3) {//包袱->石头,能赢
                    f[i][j] = max(f[i - 1][1], f[i - 1][2]) + 1;
                }
            }
            if (s[i] == 2) {
                if (j == 2) {//剪刀->剪刀,会平局
                    f[i][j] = max(f[i - 1][1], f[i - 1][3]);
                }
                if (j == 1) {//石头->剪刀,能赢
                    f[i][j] = max(f[i - 1][2], f[i - 1][3]) + 1;
                }
            }
            if (s[i] == 3) {
                if (j == 3) {//包袱->包袱,会平局
                    f[i][j] = max(f[i - 1][1], f[i - 1][2]);
                }
                if (j == 2) {//剪刀->包袱,能赢
                    f[i][j] = max(f[i - 1][1], f[i - 1][3]) + 1;
                }
            }
        }
    }
    int maxx = INT_MIN;
    for (int i = 1;i <= 3;++i) {
        maxx = max(maxx, f[n][i]);
    }
    return maxx;
}
posted @ 2024-08-03 23:29  guoguo160  阅读(17)  评论(0)    收藏  举报