题解 CF1409F Subsequences of Length Two
作者:互联网
转眼间已经快一个月没有写博客了呢
我的 dp 水平似乎都留在了 CSP 考场上那个惊险的 dp 上,最近试了几道 dp 都没做出(
最多修改 \(k\) 次,求字符串 \(\textsf{ab}\) 在子序列 \(s\) 中出现的最多次数。
原来的想法是 \(f(i, j, k)\) 表示前 \(i\) 个用了 \(j\) 次修改,有第 \(i\) 个之前(不包含) \(k\) 个 \(\textsf{a}\) 的最大答案,然后转移了一波。
调了很久才发现这样有一个大问题,这“之前”的,可能已经被修改过而并不是原来的样子了,因为这状态里并没有把最后一个位子给计算到里面去。
其实这个问题本来根本不应该存在的,只是我做这个 dp 的时候出现了一点大问题,仿佛认为每一位必须是要产生贡献的那位,所以才规定到前面一个。事实上完全不需要这样,即使当前不是产生贡献的位也完全可以用来传递贡献,dp 本来就是这样一个个状态之间传递的。
然后把哪个“不包含”去掉,重新写了转移,发现短了许多,且很快就过了。
memset(f, -0x3f, sizeof f);
f[0][0][0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 0; j <= K; j++)
for (int k = 0; k <= i; k++) {
ckmax(f[i][j][k], f[i-1][j][k] + k*(s[i-1] == b));
if (s[i-1] == a && k) ckmax(f[i][j][k], f[i-1][j][k-1]);
else if (s[i-1] != a && j && k) ckmax(f[i][j][k], f[i-1][j-1][k-1]);
if (j) ckmax(f[i][j][k], f[i-1][j-1][k] + k);
}
标签:包含,题解,贡献,传递,修改,Subsequences,CF1409F,textsf,dp 来源: https://www.cnblogs.com/Acfboy/p/CF1409F.html