[DTCPC 2024] 戈布
TernaryTree · · 题解
类似的题在 CF 好像叫做 Balanced String 来着。
首先考虑一个
问题转换为,找一个
直接考虑 dp。
则有转移:
第一个式子
然后可以对第三维滚动数组。空间降为
时间复杂度
#include <bits/stdc++.h>
using namespace std;
const int maxn = 810;
int n, m, ans;
char s[maxn];
int t[maxn];
int f[maxn][maxn][2];
int tmpf[maxn][maxn][2];
int g[maxn][maxn];
int tmpg[maxn][maxn];
signed main() {
cin >> s + 1, n = strlen(s + 1);
for (int i = 1; i <= n; i++) m += s[i] - '0', t[i] = t[i - 1] + s[i] - '0';
memset(f, 0x3f, sizeof(f));
memset(g, 0x3f, sizeof(g));
memset(tmpf, 0x3f, sizeof(tmpf));
memset(tmpg, 0x3f, sizeof(tmpg));
ans = f[0][0][0];
f[0][0][0] = 0;
g[0][0] = 0;
for (int k = 0; k <= m; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
f[i][j][0] = min(f[i - 1][j][0], f[i - 1][j][1]) + (s[i] == '1');
if (k && k <= i && k <= j) f[i][j][1] = tmpg[i - k][j - k] + k - t[i] + t[i - k];
if (k) g[i][j] = tmpg[i][j];
g[i][j] = min(g[i][j], f[i][j][0]);
}
}
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
tmpf[i][j][0] = f[i][j][0];
tmpf[i][j][1] = f[i][j][1];
tmpg[i][j] = g[i][j];
}
}
ans = min(ans, f[n][m][0]);
ans = min(ans, f[n][m][1]);
}
cout << ans / 2 << endl;
return 0;
}