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;
}

浙公网安备 33010602011771号