动态规划大学习

dp 没救了。

所以恶补了一下动态规划。

一种常常可以把指数级别复杂度优化到多项式复杂度的算法。因为有大量的状态被删去。

对于一个状态,考虑进入这个状态的最后一步是怎样的。

Part1 基础知识

无后效性

通常来说,各个状态可以用 DAG 来装填。

而用 topo 排序的顺序就可以求解出每个点上的 dp 值。

每条有向边可以表示一个点对另一个点的贡献。

因为 DAG 不会成环,所以 dp 通常具有无后效性的性质。

对 DAG topo 就是 dp 的求解过程,DAG 上的边就是 dp 的转移过程,点就是值。

入度为 \(0\) 的点就是 dp 的初始状态。

完备性

dp 状态必须考虑到可能的所有状态。

可以视情况删减一些确保更劣的状态。

比如背包 dp 背包的过程中相同重量消耗,相同集合下选取的和更小,那么这样的状态是可以被另一个状态完全击败的,这个时候就可以忽略了。

有后效性

分为取 max / min 的有后效性和取 sum 的有后效性。

对于取 max / min 的,分别对应到最长 / 最短路。对于 sum 的,可以考虑高斯消元。

Part2 例题

这部分例题是我以前做了很多道 dp 好题之后新做的,质量没有参考价值。

但是做法、理解方式非常奇异搞笑。

P17521 [ECUSTPC 2026 Fall] 天外来物

写个非常牛的想法,不需要 ad-hoc。

首先先想 \(n!\) 的暴力,考虑给每个点分配一个选取时间 \(p_i\),那么答案是

\[T_i = \max_p\sum_{k = 1}^i a_k(-1)^{[p_k < p_{k - 1}] + [p_k < p_{k + 1}]} \]

尝试转移 \(T_i\),发现 \(T_i\) 位置的贡献需要继承 \(p_{i - 1}\),与之有关,但是考虑记录 \(T_{i, j}\),但是又发现 \(j\) 维度记录了冗余信息:所有 \(p_i > p_{i - 1}\) 的都是一样的,所有 \(p_i < p_{i - 1}\) 也是一样的。

所以我们 \(j\) 只需要考虑 \(0, 1\),分别限制 \(p_i > p_{i - 1}\) 和 \(p_i < p_{i - 1}\)。

因为定义 \(p_0\) 和 \(p_n\) 不良,所以要求 \(p_0 = p_n = +\inf\)。

这个时候就可以推导出

\[\begin{cases}f_{i, 0} = \max_p\sum_{k = 1}^i a_k(-1)^{[p_k < p_{k - 1}] + [p_k < p_{k + 1}]} (p_{i} > p_{i - 1}) = - a_i + \max\left\{f_{i - 1, 0}, f_{i - 1, 1}\right\} \\ f_{i, 1} = a_i + \max\{f_{i - 1, 0} + 2a_{i - 1}, f_{i - 1, 1}- 2a_{i - 1}\}\end{cases}\]

调试可以用排列暴力来确定 dp 的正确值。

#22. 【UR #1】外星人

高手题!

先将外星人从大到小排序,设 \(f_{i, j}\) 表示考虑前 \(i\) 个外星人传到这里目前剩下 \(j\) 的方案数。

考虑转移。

  1. \(f_{i - 1, j}\) 可以让这个外星人“有效”,即这个外星人会对 \(x\) 造成变化,那么变化一定是让 \(j\) 变成 \(j \bmod a_i\),剩下的答案统计到 \(f_{i, j \bmod a_i}\) 上。

  2. \(f_{i - 1, j}\) 可以让 \(i\) 这个外星人无效,即不产生变化,因为编号更小的外星人在编号更大的外星人之后一定没用,原因是余数一定比除数小。所以可以转移到 \(f_{i, j}\),并且因为 \(i\) 号外星人可以放在剩下 \(n - i\) 个位置的任何位置,所以要乘上系数 \(n - i\)。

posted @ 2026-10-13 20:50  wangcy192  阅读(5)  评论(0)    收藏  举报