树上背包

算法相关

转移类型

常见的转移方式有两种: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_{x, i + j, 0} \to \sum_{u \in \operatorname{son}(x)} dp_{x, i, 0} \times dp_{u, j, 0} \]

\[dp_{x, i + j, 0} \to \sum_{u \in \operatorname{son}(x)} dp_{x, i, 0} \times dp_{u, j, 1} \]

\[dp_{x, i + j, 1} \to \sum_{u \in \operatorname{son}(x)} dp_{x, i, 1} \times dp_{u, j, 0} \]

\[dp_{x, i + j - 1, 0} \to \sum_{u \in \operatorname{son}(x)} dp_{x, i, 1} \times dp_{u, j, 1} \]

边界处可以选择特殊转移,或者将原先的 dp 数组转存下来。

P12444 [COTS 2025] 发好奖 / Hijerarhija

简要题意

给定一棵树,你可以给树上的点分配权值 \(v_i\)。你能得到一个点的价值 \(p_i\) 当且仅当你分配的权值大于其期望值 \(c_i\) 且其父亲的权值非零。求在你分配的权值和不超过 \(m\) 是能获得的最大价值和。

思路

这题也是一个经典的树上背包 dfs 序转移。相比于原先的模板题,该题多了一种转移,即你可以不获得该点的代价,但是为该点赋上 \(1\) 的权值。这样状态 \(dp_{i, j}\) 的前驱状态为 \(dp_{i - 1, j - 1}\)。

posted @ 2026-09-29 13:27  endswitch  阅读(5)  评论(0)    收藏  举报