给定长度为n的01串s,现要插入m个字符(0或1)求1<=i<j<k<=n+m,s[i] = 0,s[j]=1,s[k]=0的个数 (dp[n][2])
时间: 2024-09-06 11:04:10 浏览: 55
字符串编辑1
这个问题可以通过动态规划来解决。我们可以定义一个二维动态规划数组`dp[i][j]`,其中`i`表示前`i`个位置(原字符串的前`i`个字符加上插入的字符),`j`表示插入了`j`个字符之后的状态。由于我们只关心字符`1`的插入,因此状态`j`有两个可能的值,`0`表示没有插入字符`1`,`1`表示已经插入了一个字符`1`。
状态转移方程如下:
1. `dp[i][0]`表示没有插入字符`1`的情况,它可以由前一个状态`dp[i-1][0]`转移而来,即在前`i-1`个位置(包括插入的字符)没有插入字符`1`,那么在第`i`个位置有两种情况:如果`s[i-1]`是`0`,则可以选择插入一个`1`,这样`dp[i][1]`就会增加`dp[i-1][0]`个结果;如果`s[i-1]`是`1`,则不能插入字符`1`,`dp[i][0]`保持不变。
2. `dp[i][1]`表示已经插入了一个字符`1`的情况,它可以由前一个状态`dp[i-1][1]`和`dp[i-1][0]`转移而来。如果`s[i-1]`是`0`,那么可以选择插入一个`1`,`dp[i][1]`就增加`dp[i-1][0]`个结果;如果`s[i-1]`是`1`,则不能插入字符`1`,`dp[i][1]`保持不变。
初始化条件:
- `dp[0][0] = 0`,因为没有位置时,不会有插入的情况。
- `dp[0][1] = 0`,同上。
最终结果为`dp[n+m][1]`,因为它表示在插入了`m`个字符之后,最后一个字符为`1`的情况。
下面是C++代码实现:
```cpp
#include <iostream>
#include <vector>
using namespace std;
int countSpecialSubstrings(string s, int m) {
int n = s.length();
vector<vector<int>> dp(n + m + 1, vector<int>(2, 0));
for (int i = 1; i <= n + m; ++i) {
dp[i][0] = dp[i - 1][0]; // 继续保持0的状态
if (i > m) { // 如果i超过了m,意味着可以插入1
if (s[i - m - 1] == '0') {
// 如果当前字符是0,则可以插入1,并且在插入1之前的状态中寻找0
dp[i][1] = dp[i - 1][0];
}
if (s[i - m - 1] == '1') {
// 如果当前字符是1,不能插入1,但是可以在插入1之后的状态中寻找1
dp[i][1] = dp[i - 1][1];
}
}
// 如果i <= m,那么只能插入1,不能插入0,因此dp[i][1]是前一个状态dp[i-1][1]的值
if (i <= m) {
dp[i][1] = dp[i - 1][1];
}
}
// 最终结果是插入m个1之后,最后一个字符为1的情况
return dp[n + m][1];
}
int main() {
string s;
int m;
cin >> s >> m;
cout << countSpecialSubstrings(s, m) << endl;
return 0;
}
```
阅读全文