子树合并背包类型的dp的复杂度证明

版权声明:本文为博主原创文章,转载请标明出处,谢谢。 https://blog.csdn.net/lyd_7_29/article/details/79854245

状态形如f[x][j]表示x子树内选了j个,转移形如f[x][j+k]=f[x][j]f[y][k]
假设树上有n个点,第二维限制为k(最多选k个)
我们熟知,这样dp复杂度上界是n^2的。因为合并大小为a,b的子树复杂度是a*b,可以看成a子树内任选一点,b子树内任选一点进行匹配,不管怎么合并任意两个点只会在其lca匹配一次,所以是n^2的。
但是严格分析一下复杂度,可以得到更好的上界:O(nk)
首先,定义大小超过k的子树为大子树,小于k的为小子树。

一个极小的大子树一定是由若干个极大的小子树合并而成的,而且合并的过程中就会从极大的小子树变成极小的大子树。假设所有的极大的小子树的大小分别为x1,x2,x3…..xm,显然x1+x2+…+xm<=n,将这些小子树并入大子树的复杂度为k*(x1+x2+…+xm)<=nk,可以认为是每个极大的小子树被消灭掉所产生的总时间代价不超过nk

考虑一个极大的小子树(大小x<=k)内部合并上来的复杂度,由上面的分析知是x^2的
因此每个小子树内部合并的复杂度就是x1^2+x2^2+…+xm^2,xi<=k,显然当尽量多的xi取到k这个值才会更大,因为假设xi=n为定值,x1>x2,如果让x1++,x2–,上面那个值会变大。这样复杂度就是n/k*k^2=nk

最后,考虑将所有的极小大子树合并成整棵树的复杂度,显然极小的大子树互不包含,因此极小的大子树个数不会超过n/k个,而每合并两个的时间开销是k^2,因此这部分复杂度是n/k*k^2=nk

综上,复杂度上界为O(nk)

展开阅读全文

没有更多推荐了,返回首页