题解:P13894 [蓝桥杯 2023 省 C] 填充
weifengzhaomi · · 题解
题意比较明了,这里不在复述。
思路 1.0
我们考虑用贪心。
我们统计出所有两个相邻字符串相等的数量,然后在统计有多少个 ?,遇到时把它换成上一个字符答案加一即可,如果上一个字符是 ?,答案也加一。
for (int i = 2;i <= n;i++)
if (s[i] == s[i - 1] || s[i] == '?' || s[i - 1] == '?') ans++,i++;
思路 2.0
我们考虑用动态规划。
设 0 结尾的最大子串数,1 结尾的最大子串数。
首先,我们不必考虑前一个字符,就算前一个字符满足了我们动态规划所需要的字符,但我们也只会赋值给当前的状态,所以,我们要考虑前二个字符。
如果前二个字符是相等的,或者其中有的是 ? 时,当前状态就要和前二个状态的值加一取一个最大值。
cin >> s;
n = s.size();
for (int i = 2;i <= n;i++){
dp[i][0] = dp[i - 1][0];
dp[i][1] = dp[i - 1][1];
if (s[i - 1] == '0' || s[i - 1] == '?')
if (s[i - 2] == '0' || s[i - 2] == '?'){
dp[i][0] = max(dp[i][0],dp[i - 2][0] + 1);
dp[i][0] = max(dp[i][0],dp[i - 2][1] + 1);
}
if (s[i - 1] == '1' || s[i - 1] == '?')
if (s[i - 2] == '1' || s[i - 2] == '?'){
dp[i][1] = max(dp[i][1],dp[i - 2][0] + 1);
dp[i][1] = max(dp[i][1],dp[i - 2][1] + 1);
}
}
cout << max(dp[n][0],dp[n][1]) << endl;