DP
DP 心得总结
DP 初步
dp 难在思考,状态转移方程最为重要,我们要认真思考,将整个思路变为状态转移方程。
背包
最简单的 dp ,要知道背包的状态,背包中所存储,背包中的空间的缩小也是很重要的,我们也要尽量把多维缩小,优化时间复杂度可以更好的实现代码。
状态:
-
代价等于价值,我们可以直接设置 \(dp_i\) 表示价值 \(i\) 也表示价值,如P2392 kkksc03考前临时抱佛脚。
-
代价为状态,\(dp_i\) 表示通过 \(i\) 的代价得到的最大价值,如P1048 [NOIP2005 普及组] 采药。
背包分类:
- 01背包,选还是不选。P1048 [NOIP2005 普及组] 采药
- 完全背包,可以无限选择。P1616 疯狂的采药
- 多重背包,可以选多个。P1833 樱花
- 分组背包,一个组里只能选一个。P1757 通天之分组背包
- 有依赖背包,两种物品一定要一起选择。P1064 [NOIP2006 提高组] 金明的预算方案
- 混合背包,将上面的混合。P2851 [USACO06DEC] The Fewest Coins G
优化:
- 滚动数组,如果 \(dp_{i,j}\) 的状态只和上一行有关,我们就可以使用滚动数组。
- 如果状态具有单调性,那么我们就可以优化为 \(1\) 维数组。
- 多重背包 二进制优化,不难证明有了在 \([1,n)(n|2)\) 所有 \(2\) 的幂,我们就可以得到所有 \(\le n\) 的数。
状压dp
状压 dp 容易实现,难在状态转移方程,要想实现状压 dp 我们先要会位运算。
之后我们就可以把一个 bool 类型的 \(01\) 串压为一个二进制的数,这样就可以储存在数组中。
如 \(i = 10\) 时可以表示 \(1010\),也就是选取了第 \(4\) 个和第 \(2\) 个。
状态:\(dp_{i,j}\) 总是表示在选取了 \(i\) 方案之后留下 \(j\) 所得到的最大价值。
方程:\(dp_i = max(dp_{i ⊕ 1 << k}+v_{k,j})\)
区间 dp
区间 dp 是用来求一段区间中操作最大值的,主要思想就是大的区间化为小的区间。

若我们要求上面 \([l,r]\) 的操作最大值,我们可以这么求。

先求出 \([l,k]\) 和 \([k + 1,r]\) 一步一步分解,最后就可以分解成最小的已知的值。
这样就可以得到 \([l,r]\) 的值。
状态:\(dp_{i,j}\) 通常表示 \([i,j]\) 中的操作最大值。
方程:\(dp_{i,j} = \max(dp_{i,k} + dp_{k + 1,j} + v_{i,j})\)
add-2023.10.13
好久没有碰 dp 了,复习一下,并且增加 树形 dp。
树形 dp
顾名思义,树形 dp 是一种在树上进行 dp 的操作,别看要用到树,其实树形 dp 的状态转移方程是最容易想的。
例题
题目描述
树上每个点会让自己到 \(N(\text{包含自己})\) 个点的路径之上的所有的结点的权值 \(+1\),请求出树上每一个点的权值。
题目分析

在这样的一棵树中节点 \(1\) 的权值应该是 \(2(1,2) \times 3(4,5,6) + 5(2,3,4,5,6) + \sum{d[root(x)] * }\)

浙公网安备 33010602011771号