给一个字符串 \(s\) 包含 \(0, 1, ?\) 。
定义一个 \(01\) 串 \(s\) 的 \(cost\) 为:选择 \(s\) 的任意一个子段 \([l, r]\) 并 \(reverse\) 。将 \(s\) 变为一个非降序序列时的 \(reverse\) 最小次数即 \(cost\) 。
你可以让 \(s\) 的 \(?\) 换成 \(0/1\) ,使新 \(s\) 的 \(cost\) 最小。输出 \(cost\) 最小的 \(s\) 。
首先分析一个 \(01\) 串 \(s\) 的 \(cost\) ,即需要 \(reverse\) 多少次。不难和证明发现使 \(s\) 非降序需要 \(reverse\) 的次数等于 \(s\) 中 \(10\) 子串的个数。
可以使用 \(navie\) 的 \(dp\) 做法,\(dp_{i, j}\) 为考虑到前 \(i\) 个位置,以 \(j\) 结尾,可以产生的 \(10\) 串数量。
view
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int dp[300005][2], pre[300005][2];
void solve(){
std::string s; std::cin >> s; int n = s.length(); s = " " + s;
for (int i = 1; i <= n; i++) {
dp[i][0] = dp[i][1] = 1 << 30;
if (i == 1) {
if (s[1] == '?') {
dp[1][0] = dp[1][1] = 0;
}
else if (s[i] == '1') {
dp[1][1] = 0;
}
else if (s[i] == '0') {
dp[1][0] = 0;
}
}
else {
if (s[i] == '?') {
dp[i][0] = std::min(dp[i - 1][0], dp[i - 1][1] + 1);
pre[i][0] = dp[i - 1][0] < dp[i-1][1] + 1 ? 0 : 1;
dp[i][1] = std::min(dp[i - 1][0], dp[i - 1][1]);
pre[i][1] = dp[i - 1][0] < dp[i-1][1] ? 0 : 1;
}
else if (s[i] == '1') {
dp[i][1] = std::min(dp[i - 1][0], dp[i - 1][1]);
pre[i][1] = dp[i - 1][0] < dp[i-1][1] ? 0 : 1;
}
else if (s[i] == '0') {
dp[i][0] = std::min(dp[i - 1][0], dp[i - 1][1] + 1);
pre[i][0] = dp[i - 1][0] < dp[i-1][1] + 1 ? 0 : 1;
}
}
}
// std::cout << dp[n][0] << ' ' << dp[n][1] << '\n';
std::vector<int> ans;
int p = dp[n][0] < dp[n][1] ? 0 : 1; ans.push_back(p);
for (int i = n; i >= 2; --i) {
p = pre[i][p];
ans.push_back(p);
}
std::reverse(ans.begin(), ans.end());
int m = ans.size();
for (int i = 0; i < m; i++) std::cout << ans[i]; std::cout << "\n";
}
int main() {
int _ = 1; std::cin >> _;
while (_--) solve();
return 0;
}
- Educational Codeforces Binary String Roundeducational codeforces binary string educational codeforces string round educational codeforces copying binary educational codeforces strings binary educational codeforces round rated educational codeforces round 151 construction educational codeforces round educational codeforces round 147 cf-educational educational codeforces round educational codeforces round 158