树上背包
算法相关
转移类型
常见的转移方式有两种:dfs 合并和 dfs 序。
通常只有一种情况我们会用 dfs 序:物品体积不为 \(1\) 且物品价值不为 \(1\)。在此基础上若该转移不依赖树形结构,则时间复杂度 \(O(n W)\),否则时间复杂度 \(O(n ^ 2 W)\)。
至于其他的形式,我们一般采用 dfs 合并转移,只需要精细地考虑上下界问题即可。可以证明该方法能做到 \(O(n ^ 2) / O(n W)\)。
基于 dfs 序的转移
dfs 合并是比较常见的,因此我们只讨论 dfs 序转移的做法。
将树上节点按后序遍历重编号,这样我们按 \(1 \sim n\) 顺序枚举时能够确保每次取出来的节点一定没有父亲。
接下来我们需要对当前枚举的 \(i\) 做取舍,对于状态 \(dp_{i, j}\) 而言:
- 选 \(i\):
那么变成了 \(i - 1\) 的子问题,则其前驱状态为:\(dp_{i - 1, j - v_i}\)。
并且还需要确保 \(j \ge v_i\)。
- 不选 \(i\):
那么你一整棵子树都不能选,其前驱状态为:\(dp_{i - sz_i, j}\)。
习题
P2014 [CTSC1997] 选课 / U53204 【数据加强版】选课
模板。前者可以乱写通过,后者需要精细地卡一下上下界。
#160. 树形背包
模板。dfs 序转移。
Div. 1 C. Karen and Supermarket
简要题意
给定一棵树,树上点有两组点权 \(a, b (\forall a_i < b_i)\)。对于每个点 \(x\),你可以选择 \(a_x, b_x\) 或不选。但是当该点选择 \(b\) 时,其父亲也必须选择 \(b\)。求在权值和不超过 \(m\) 能选的最多点数。
思路
可行性转最优性:设计 \(dp_{x, i, 0 / 1}\) 表示以点 \(x\) 为根的子树选择了 \(i\) 个点,且点 \(x\) 是否选 \(b\) 的最小权值和。这样是一个经典的转移形式,可以做到 \(O(n m)\)。
ABC F - Components
简要题意
对树的导出子图的连通块数量恰好为 \(x\) 的方案计数。
思路
设计 \(dp_{x, i, 0 / 1}\) 表示以点 \(x\) 为根的子树内划分为 \(i\) 个连通块,且点 \(x\) 选 / 不选的方案数。有转移:
边界处可以选择特殊转移,或者将原先的 dp 数组转存下来。
P12444 [COTS 2025] 发好奖 / Hijerarhija
简要题意
给定一棵树,你可以给树上的点分配权值 \(v_i\)。你能得到一个点的价值 \(p_i\) 当且仅当你分配的权值大于其期望值 \(c_i\) 且其父亲的权值非零。求在你分配的权值和不超过 \(m\) 是能获得的最大价值和。
思路
这题也是一个经典的树上背包 dfs 序转移。相比于原先的模板题,该题多了一种转移,即你可以不获得该点的代价,但是为该点赋上 \(1\) 的权值。这样状态 \(dp_{i, j}\) 的前驱状态为 \(dp_{i - 1, j - 1}\)。

浙公网安备 33010602011771号