关于树形背包时间复杂度为什么会比想象中少一阶

Upd 2024年12月18日

将树拍到 DFS 序上,合并两个子树时认为复杂度是左子树 DFS 序最大的 V 个点和右子树 DFS 序最小的 V 个点个数相乘,则整个序列中只有下标差 2V1 的点对有贡献,所以是 O(nV)

Upd 2022年10月3日

对于树上的任意一点 x,我们设其贡献的时间复杂度为 T(x)

x 的儿子大小分别是 p1,,pc,设 x 的大小为 p0=1+i=1cpi,则

T(x)=1+p1+p2(1+p1)+p3(1+p1+p2)++pc(1+p1++pc1)=1+(1+i=1cpi)21i=1cpi22=12(1+p02i=1cpi2)

发现不论以什么顺序合并儿子复杂度都是相同的。

总复杂度

i=1nT(i)=12(n+n2)

相当于把 pi2 这部分负贡献给这个儿子,抵消后只剩根节点 size 的平方了。

远古

下面的东西太 naive 了,差不多别看了,谢谢。

思路来自 Konata,有删改及本作者的想法

如果正常想,每个节点都要进行 O(n2) 的背包,则时间复杂度为 O(n3),其实不然。

假设 n 个节点的树形背包的时间复杂度为 f(n)

那么假设根节点下面的子树大小分别为 p1,p2,,pk,子树大小 pi 对应的子树根节点下面的子树大小分别为 gi,1,gi,2,,gi,si

f(n)=i=1kf(pi)+i=2k(pi×j=1i1pj)=i=1kf(pi)+1i<jkpi×pj=i=1kf(pi)+(i=1kpi)2i=1kpi22=12(n1)2+i=1kf(pi)12i=1kpi212n2+i=1k(f(pi)12pi2)=12n2+i=1k(12(pi1)2+j=1si(f(gi,j)12gi,j2)12pi2)12n2+i=1kj=1si(f(gi,j)12gi,j2)12n2+(f()12()2)12n2=O(n2)

特殊得,如果背包的容量上限为 V,则总时间复杂度为 O(nV)

posted @   ShaoJia  阅读(244)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示