关于 dp 套 dp 的一些思考--zhengjun

dp 套 dp 一般有三种形式:

  • 暴力搜出一种东西的状态,发现数量不大,建出自动机开始跑;

  • 有关字符串的匹配问题,例如 kmp 或 AC 自动机上;

  • 有关 LIS/LCS 问题的可以使用一种特殊的内层 dp 优化状态。

前两个没什么好讲的,讲一下第三个。

LIS

\(f_i\)\(1\sim i\) 的 LIS 长度(不一定要 \(i\) 结尾)。

发现 \(f_i\le f_{i+1}\),同时也有 \(f_{i+1}-1\le f_i\)

所以 \(f_{i+1}-f_i\in\{0,1\}\),于是可以状态压缩这个差分数组。

但是这样子做需要从小到大加数,每次在加的位置改为 \(1\),后面第一个 \(1\) 变成 \(0\)(如果没有就不管)。

这样可以把 LIS 压缩成 \(2^n\)

例题

HHHOJ #1255. 「NOIP 2023 模拟赛 20230716 D」拳击比赛 加强版

直接这么压缩 LIS,复杂度 \(O(nm4^n)\) 无法通过。

发现每一位一次填数的时候,如果填数的集合为 \(S\),dp 的差分数组为 \(1\) 的集合为 \(T\)

那么有 \(T\subset S\),所以状态数实际上是 \(O(3^n)\),而且有很多状态其实也是无效的。

时间复杂度 \(O(nm3^n)\),看似 \(1e9\) 无法通过,实际上加个非零剪枝就可以做到 1s 以内。

LCS

LCS 和 LIS 是差不多的。

\(f_i\)\(s_{1\sim i}\) 与目标串的 LCS。

显然也有 \(f_i\le f_{i+1},f_{i+1}\le f_i +1\)

还是状压 \(f_{i+1}-f_i\in \{0,1\}\),每次加入一个字符的时候,预处理后继状态即可。

例题

BZOJ #3864. Hero meet devil

就是这么压缩 LCS 就行了。

posted @ 2023-07-16 19:49  A_zjzj  阅读(61)  评论(0编辑  收藏  举报