题解 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);
			}
posted @ 2021-11-05 19:24  Acfboy  阅读(24)  评论(0编辑  收藏  举报