DP 概论
对于一个题目,我们有暴力搜索算法。而 dp 就是尽可能将同一类的东西合并到一个状态上。
如何检查 dp 的正确性?
- 检查集合内部转移是否一致。
- 检查方案数是否正确。
1 基础 dp 方向
1.1 状压 dp
有好几种状态压缩的方式:
- 记录“选了哪些东西”这样的信息,可以用一个长度为 的 01 串,对应一个十进制数。
- 记录可重无序集合:如果不关心顺序,只关心它们分别出现了多少值,可以记录无序集合,如果集合内的数字之和保证小于等于某一个数 ,那么状态的个数小于 的分拆数,大概 以下的分拆数能过。
- 网格图,考虑一行一行转移,然后要记录 行的信息,比如黑色格子组成的连通块,使用最小表示法:考虑同一个连通块上所有点用一个数字来表示,但是从左到右数字第一个出现的位置符合升序。这样就可以一格一格转移。
- 插头 dp:高进制状压。可以自己定义的东西。
其实相当于哈希了。状态给他搞成一个方便处理的数字或者数组。
1.2 树形 dp
换根 dp:先求出子树内的所有点到自己的影响,然后求出子树外的所有点到自己的影响,先从下往上做,然后从上往下做。
树形背包:背包大小为 的树形背包,复杂度为 。
拓扑序相关:
如果带修:结合树剖线段树等算法一起做,用矩阵。
1.3 区间 dp
什么时候会想到区间 dp:所有操作区间在原序列中要么无交要么包含的情况。例如石子合并问题,操作的区间(相对于原序列)要么无交要么包含。
再例如从一些区间内找出最多的区间使其无交或包含,也可以区间 dp。
1.4 数位 dp
如果考虑进位的,从低到高来;考虑比较大小的,从高到低来(比如某一个区间,那么考虑是否和原数前面几个数都一样),需要记录的记录一下就好了。
1.5 自动机上 dp
AC 自动机上可以 dp。但是我们现在说的是自己建立自动机的 dp:三步骤:考虑我们的状态,将每个可行状态当成一个节点,然后搜索出转移,最后直接跑 dp。算出的是精确状态数,可能可以缩小一些状态数。
这个做法是建立了一个自动机,因为自动机其实是基于 dp 建立的所以我们叫它 dp 套 dp。
一般用来解决这样的问题:
- 如果给定一个字符串,可以使用 dp 判断它是否合法。
- 需要求每个位置在许多字符中任取的时候有多少合法的串。
我们的方法是:直接对记录状态的那个 dp 数组进行压缩,然后根据内层 dp 的转移,建立一个自动机,然后在这个自动机上跑 dp。
QOJ1251. Even Rain
这题目,我设计状态的时候,考虑钦定目前 dp 的位置是前缀 max,然后状态 ,转移 并且很复杂;可以将前缀 max 的位置放进状态,然后 转移。
给我的一个教训是:如果某一个状态,要么要加入进状态里面,要么要 dp 它,都是躲不开的,那么考虑加入进状态可能会比 dp 它少判断很多东西,并且更优。
HDU2484
这题是一个树形期望 dp,对每一个 和 相同的元素,其 的 dp 值可能不一样,但是其 值是一样的,我们就可以记忆化搜索,只需要 种状态而不是 种。
为了优化 dp 的复杂度,需要找等价的 dp 状态。为了找等价的 dp 状态,考虑 dp 的转移具体和什么有关,有没有办法从状态里去掉不需要的东西。例如此题,虽然往回的状态需要整个 mask,但转移的系数只和后面的和有关。
2 基础 dp 优化
2.1 单调队列优化
考虑这样的 dp 式子:
是最大的 满足 ,其中 , 单调递增。
转移的时候,首先注意到如果一个数比你大而且 还比你小,那么你就没了。其次由于 单调递增,可以不断从前面 pop 元素,直到如果该元素 pop 了下一个元素就大于 了。
这样就从 转移变成了 转移。
2.2 整体转移
QOJ 1586. Ternary String Counting
一个只包含 的长度为 的序列,有 个限制形如第 到 位中有 种数。求符合限制这样的序列的个数。
表示填到第 个数,前面第一个跟它不一样的位置在 ,第二个不一样的位置在 的方案数。
有 状态, 做完整个 dp 的算法:
的时候考虑什么时候第一次出现了 。可以从 转移,,或者从 转移,。
的时候只能从 转移。
但是这个 pull 形式很难做整体转移优化。考虑做 push。
发现这个形式挺好的,自然考虑令 表示 矩阵。
考虑从 转移到 。发现第一种转移是不改变,第二种转移是一个行求和,第三种转移是一个列求和,并且每一个位置最多被填一次。
考虑挂在 上的限制的作用。就是将 只保留一个矩形区域。
那么你可以维护每一行每一列的和,并且加点的时候给其所在行和列都标记上这个点有值;删点的时候从两边往中间删,直到删到矩形区域内。
每一个点最多被加一次删一次,所以时间复杂度 。
关于一些零碎,例如初值怎么设置,都可以尽量朝着兼容方向想,并不是思考的关键。
其实对于这类整体转移问题一般都是用 push,因为这样可以描述为一个矩阵的变换,比较好进行优化。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!