树上背包问题是树形结构上的一种背包问题,通常涉及在树的节点或边上进行选择,以满足特定的约束条件,同时最大化或最小化某个目标函数(如权值和)。这类问题常见于计算机科学中的图论和动态规划领域。

树上背包是树形 dp 的常见模型,通常是分组背包的变形,而分组背包的本质就是多个泛化物品不断相加。因此掌握泛化物品的合并的方法有助于理解转移的过程。 此类问题一般也可以用 DFS 序、多叉转二叉等方法解决。

解题范式

转分组背包解法

伪代码

 

泛化物品求并解法

伪代码

 

例题:二叉苹果树

题意简述:在一个二叉树中,每个边有一个权值。我们要保留 条边组成的连通分量(必须包含根节点),求边权和最大值。

朴素解法:树形 dfs+ 分组背包合并

对于每个节点 ,我们用 表示在以 为根的子树中选择 条边(含连接边)所能获得的最大权值和。则状态转移方程为:

其中 的某个子节点, 是边 的权值。

TC: ,其中 是节点数, 是需要选择的边数。 SC:

分组背包(边界优化)

的循环范围可以进行一些优化,最终得到边界优化版本.

注意:该方法的 TC 为 而不是 ,其中 是节点数, 是需要选择的边数。具体证明过程可参考 2.1.2 复杂度分析

Seealso

更详细的解析过程见 2.1 分组背包

泛化物品求并

来源: 徐持衡 - 国家集训队2009论文集 浅谈几类背包题

树形dp -(树上背包类) 中列出了树上背包问题的基础解法和几种优化解法,其中泛化物品求并解法是几种高效的优化解法中实现较为简单(但同样需要理解成本)的一种解法,值得重点掌握。

区别与分组背包的 dp 定义,泛化物品求并解法的 dp 定义为: 表示从已遍历的子节点中选择 条边且必选节点 u所能获得的最大权值和。在此题中,选择节点 u 表示选择连接 u 与其父节点的边。

Note

注意这里是“泛化物品求并”解法,而不是单纯的“泛化物品”解法,因为上述分组背包的解法本质也是泛化物品的思想。要使用泛化物品求并解法,必须精心设计 dp 的定义,使得 dp 状态能够满足“可并”的性质。更多参考 2.4 泛化物品求并解法

Note

理解这个解法的核心是要理解 的含义, 这个解法里 表示遍历到当前节点 u 时选节点 u 以及从其他已遍历的节点中选 j-1 个节点的解. 这里有几点需要注意:

  • dfs 遍历是个有来有回的过程, 最开始从虚拟根节点出发, 来来回回逐个子节点 dfs 遍历,最后回到虚拟根节点, 因此当前已遍历节点这个集合是不断在变化的, 所以 也需要不断更新, 不可能一次遍历就完成所有的更新.
  • 选的节点都是真节点, 不包括虚拟根节点 (因为 dep 从 0 开始)
  • j -1 个节点中一定包含虚拟根节点到 u 的路径上的节点 (不然也遍历不到 u)

回到 dfs(u, dep) 的过程, 当循环到其子节点 s 时,

  • f[s][j] = f[u][j - 1] + v[s]; 的含义是: 遍历 s 节点, 设当前已遍历节点集合为 , 则 表示接下来遍历到 s, 选 s 及从 中选 个节点的解, 注意从虚拟根节点到 s 路径上的点 (包含 u) 是在这 j-1 个节点中的, 剩下的节点则是从 N_u 中 u 的其他已遍历的子树中的节点选的.
  • dfs(s, dep + 1); 递归遍历 s 子树,直至遍历完其所有子节点,最后回到 u. 经过这一步后, 已遍历的点集为 , 其中 是 s 子树所有点 (含 s), 此时 中的点对应的 f 是已经更新好的状态, 符合其定义.
  • f[u][j] = max(f[u][j], f[s][j]); 因为前面遍历了 s 子树的所有节点 ,已遍历的点集变为 , 而 的状态还停留在已遍历点集为 的状态, 所以需要更新 的状态, 因为如果不选 s, 则 s 子树所有的点也不能选, 因此现在的 可以认为是从已遍历的点集 中选 u 不选 s 共选 j 个节点的解, 而 则是从已遍历的点集 中选 u 选 s 共选 j 个节点的解, 两种情况不可能同时发生, 只能取其一, 因此 便是从已遍历的点集 中选 u 共选 j 个节点的解, 符合定义, 即 的状态得到了更新.
  • 至此完成了对子节点 s 的处理, 回到 u, 继续处理 u 的其他子节点, 等处理完所有子节点, 的含义就变成了从已遍历的点集 中选 u 共选 j 个节点的解, 特别的,当节点 u 为虚拟根节点时, 最后的含义就是从所有真节点 (不含虚拟节点) 中选 j 个节点的解, 也就是最终的答案.

Note

可以看出,带上下边界优化的分组背包解法和泛化物品求并解法的时间复杂度都是 ,但泛化物品求并解法的实现更为简洁,且避免了双重枚举,效率更高一些。因此在实际应用中,推荐优先考虑使用泛化物品求并解法来解决树上背包问题。 但从实现难道和理解难度上来看,带上下边界优化的分组背包解法更容易被理解和实现。因此在学习阶段,可以先掌握带上下边界优化的分组背包解法,理解其原理后,再学习泛化物品求并解法,以便更好地理解树上背包问题的本质。

例题:选课

题意简述:在大学,有 门课来学习,每个课程有一个先修课,或者没有(要学习某门课,必须先学习它的先修课)。学一门课可以得到相应的学分。请问学 门课,最多能得多少学分。

典型的树上背包问题,这里就仅列两种解法。

分组背包(边界优化)

DP 定义 表示在以节点 为根的子树中选择 个节点(包含节点 )所能获得的最大学分和。

泛化物品求并

DP 定义 表示从已遍历的子节点中选择 个节点且必选节点 u所能获得的最大学分和。在此题中,选择节点 u 表示选择课程 u。

例题:有线电视网

给定一个树形结构。其中根节点是足球比赛的现场,叶子节点是用户终端,其他节点就是转播站。每条边都有一个边权,表示信号传递的消费。每个叶子都有一个点权,表示每个用户准备的钱数。

请问在不亏本的情况下,最多能让多少用户看到比赛? (注意不是让赚的钱最多)

分组背包

分组背包(边界优化)

分组背包(边界优化 + 空间优化)

更多相关例题