题解:P11218 【MX-S4-T2】「yyOI R2」youyou 不喜欢夏天
posted on 2024-10-20 13:30:26 | under | source
简单 dp 题。
观察到 yy 交换的列一定满足:youyou 在这列恰选了一个格子,该格子为黑色,且另一个格子为白色。称这种列为合法列。
于是可以直接做 2D 的 dp,设 \(f_{i,j,S}\) 表示考虑了前 \(i\) 列、总共有 \(j\) 个合法列,且第 \(i\) 列的选择情况是 \(S\) 时的最大价值(黑减白)。答案就是 \(\max \{f_{i,j,S}-\min(2m,j)\}\),复杂度 \(O(n^2)\)。
然后观察到最终答案不可能落在 \(0<j<2m\),因为此时合法列产生的总贡献为负,而我们可以将合法列填充为两个都选使得贡献为 \(0\)。
于是,可以强行让 \(j>0\) 的都减去 \(2m\),这样做答案肯定不会更优,而且根据上面讨论又一定包含最优答案,所以没错。
这样第二维只需记录 \([j>0]\),复杂度 \(O(n)\),带个小常数。
代码
#include<bits/stdc++.h>
using namespace std;
#define MAX(a, b) a = max(a, b)
const int N = 2e6 + 5;
int T, n, m, f[N][3][2], ans, v[3], pd[3];
char a[N], b[N];
inline int val(char c) {return c == '1' ? 1 : -1;}
inline bool chk(char now, char pre) {return now == '1' && pre == '0';}
signed main(){
cin >> T >> T;
while(T--){
ans = 0;
scanf("%d%d%s%s", &n, &m, a + 1, b + 1);
memset(f, -0x3f, sizeof f);
for(int i = 1; i <= n; ++i){
v[0] = val(a[i]), v[1] = val(b[i]); v[2] = v[0] + v[1];
pd[0] = chk(a[i], b[i]), pd[1] = chk(b[i], a[i]);
f[i][0][pd[0]] = v[0], f[i][1][pd[1]] = v[1], f[i][2][pd[2]] = v[2];
if(i > 1){
for(int S = 0; S < 3; ++S)
for(int p = 0; p < 2; ++p)
for(int S2 = 0; S2 < 3; ++S2){
if((S == 0 && S2 == 1) || (S == 1 && S2 == 0)) continue;
MAX(f[i][S2][p | pd[S2]], f[i - 1][S][p] + v[S2]);
}
}
for(int j = 0; j < 3; ++j) MAX(ans, max(f[i][j][0], f[i][j][1] - 2 * m));
}
printf("%d\n", ans);
}
return 0;
}

浙公网安备 33010602011771号