题解: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;
}

posted @ 2026-01-15 08:19  Zwi  阅读(2)  评论(0)    收藏  举报