上限为k的树形背包复杂度证明
参(zhao)考(chao)博客:lnzwz 树形背包总结
普通树形背包:
树形背包一般是设 表示当前子树内选择了 i 个点(或者连通块大小为 i )的贡献。
对于每个点 u,第一层枚举所有儿子 v,第二层枚举 v 中选了 j 个点,第三层枚举之前的儿子们(或者加上根)选择了 k 个点,将 j+k 进行合并。
因为要省去枚举儿子 v 的空间,所以要谨记滚动优化带来的枚举顺序问题,如果用 k 更新 j+k,则需要倒序枚举。
复杂度为 n^2,简单的证明和例题:[HAOI2015]树上染色
上限为k的背包:
2023 ICPC 济南站 B题,求将树切成大小为 k 或 k+1 的块的方案。
这种题我们 的第二维只需要维护到 k+1。此时的时间以及空间复杂度均为 O(nk)。
代码中只要把枚举上界改为 即可(两棵子树和的上限也要改为k)。
证明有如下两种方式:
一、分类讨论:
复杂度瓶颈在于枚举父亲 u 的连通块大小,枚举儿子 v 的连通块大小进行合并。将所有的合并行为分成两种情况:
1:两个枚举上界均为子树大小 siz:说明我们要合并的子树大小都小于 k,我们把所有 siz 小于 k 的树单独拿出来,会发现第一种情况相当于只在这些树中进行树形背包,假设每棵树大小为 ,根据普通的树形背包复杂度,这些小树的复杂度之和为 ,根据基本不等式可得复杂度上限为 。即大小均为 k,有 n/k 个。
2:两个枚举上界至少有一个为 k:发现这种情况子树与它的父亲合并之后总和大于 k,因此每个子树可以看做只被合并一次(之后只需枚举到k),设这些子树大小为 ,则复杂度上限为 。例子为菊花图。
二、数形结合:
更优美些的证明:将树用dfs序拍扁成序列,父亲与儿子的关系就形如线段树的结构。
在父亲合并儿子时,可以视作合并两个线段,左边线段取后 x 的长度,右边线段取前 y 的长度,满足 x+y<k。由于任意一次合并的线段位置都是唯一的,所有的合并复杂度相当于 n 中长度不超过 k 的子串个数。复杂度为 O(nk)。
__EOF__

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具