DP套DP

该技巧通常用来求满足某个要求的元素数量,而对于要求的判定需要 DP 解决。

因此我们将判定 DP 的结果作为计数 DP 的状态来进行计数。

P4590 [TJOI2018] 游园会

题意:给你一个字符串 \(s\),求满足条件的字符串 \(t\) 的数量:\(\vert t\vert = n,\ \text{lcs}(s, t) = i,\ \text{"NOI"} \notin t\)

对每个 \(i \in [0, \vert s\vert]\) 求出答案。\(\vert s\vert \le 15,\ n \le 10^3,\ \sum = \{\text{N},\text{O}, \text{I}\}\)

\(f_{i, j}\) 表示 \(t\) 的前缀 \(i\)\(s\) 的前缀 \(t\) 的 lcs(最长公共子序列):

\[f_{i, j} = \begin{cases} f_{i - 1, j - 1} + 1 & t_i = s_j\\ \\ \max(f_{i - 1, j},\ f_{i, j - 1}) & t_i \ne s_j \end{cases} \]

要想得到 \(f_i\),我们只需知道 \(f_{i - 1}\)\(t_i\),且每种方案唯一对应一组 \(f_{i - 1}, t_i\)

\(f_{i}\) 压入状态减小复杂度。\(dp(i, f_i)\) 表示考虑了前 \(i\) 个字符,第 \(i\) 维 dp 数组为 \(f_i\) 的方案数,枚举 \(t_i\) 转移

合法的 \(f_{i}\) 实际很少,注意到 \(0\le f_{i, j} - f_{i, j - 1} \le 1\),每一种合法方案差分后能唯一对应一个长度为 \(\vert s\vert\) 的二进制数。

对于子串的限制,再记录一维 \(k\) 表示匹配到 "NOI" 的哪一位即可。

预处理每种 \(f_{i - 1}\) 以及 \(t_i\) 会转移到哪个 \(f_i\),时间复杂度 \(O(2^{\vert s\vert} n)\)submission

CF578D LCS Again

题意:给定字符串 \(s\),求满足 \(\text{lcs}(s, t) = n - 1\) 的字符串数量。\(n \le 10^5\)

继续延续上题做法不是很牛,复杂度高达 \(2^nn\)

考虑哪些状态是一定无用的。\(\text{lcs}(i, j) \le \min(i, j)\),后缀 \(i, j\) 能匹配的最大长度是 \(\min(n - i, n - j)\)

必须满足 \(\min(i, j) + \min(n - i, n - j) = n - \vert i - j\vert \ge n - 1\) 才可能对答案产生贡献。

需要考虑的状态一共就三个:\(f_{i, i - 1},\ f_{i, i},\ f_{i, i + 1}\)

再注意到 \(f_{i, j} \ge \min(i, j) - 1\),否则也不能产生贡献。

\(dp_{i, 0/1, 0/1, 0/1}\) 表示 三项分别为 \(\{i - 2, i - 1\},\ \{i - 1, i\},\ \{i - 1, i\}\) 的方案数,复杂度 \(O(\vert \sum\vert n)\)

submission

posted @ 2024-10-07 07:47  Lu_xZ  阅读(5)  评论(0编辑  收藏  举报