试题 G:子串简写
动态规划
设
f
[
i
]
f[i]
f[i] 表示字符串 [0,i]
范围内能够简写的子串个数,
n
u
m
[
i
]
num[i]
num[i] 表示字符串 [0,i]
范围内含有字符 c1
的个数。
那么有一下递推关系:
-
s[i] == c2 && s[i - k + 1] == c1
f [ i ] = f [ i − 1 ] + n u m [ i − k + 1 ] f[i]=f[i-1]+num[i-k+1] f[i]=f[i−1]+num[i−k+1]
-
其余情况
f [ i ] = f [ i − 1 ] f[i]=f[i-1] f[i]=f[i−1]
但是若将上述思路的空间开销较大,无法通过所有测试用例,但是在上述思路的基础上我们可以进行简化。
观察可知,递推关系用到的是与前一项的关系且只会用到一次,因此我们可以不用数组来存储,而是采用变量 n
和 ans
,在每次遍历的时候进行更新,降低空间开销。
#include <iostream>
#include <string>
using namespace std;
int main() {
int k; // 长度
string s; // 字符串
char c1, c2; // 首尾字符
cin >> k >> s >> c1 >> c2;
long long n = 0, ans = 0;
for (int i = 0; i < s.length(); i++) {
if (i - k + 1 >= 0 && s[i - k + 1] == c1) {
n++;
}
if (s[i] == c2) {
ans += n;
}
}
cout << ans << endl;
return 0;
}