眾所周知,樹上背包如果上下界都卡緊了復雜度會是 \(O(nm)\),下面來進行這一點的證明。
以下設節點總數為 \(n\),背包容量最大是 \(m\)。
合並兩個泛化背包的復雜度為 \(O(s_1s_2)\),其中 \(s_1\) 是第一個泛化背包的容量,\(s_2\) 是第二個背包的容量,但這個復雜度是在背包容量不設上限的情況下。
而在樹上背包中,容量是有上限的。做樹上背包的過程,實際上就是把 \(n\) 個節點合並到一個背包的過程,顯然,合並的總次數是 \(O(n)\) 的。
合並過程的時間復雜度顯然只跟 \(s_1,s_2,m\) 有關系,其中 \(s_1,s_2\le m\),代表的含義是兩個背包分別的容量。不難發現,合並這兩個背包的復雜度應該是 \(O(\min(s_1+s_2,m)\times \min(s_1,s_2))\),之所以有這兩個式子是因為我們首先枚舉最終的背包的容量是多大,然后枚舉較小背包放多少個。
在實際操作中,我們不需要比較哪個背包較小,我們只需要給下界設置一個合適的值,設 \(i\) 為枚舉的最終背包容量,\(j\) 是當前背包放多少個,只需要設置一個下界讓 \(i-j\) 滿足不超過另一個背包的值即可。不難發現這和直接枚舉較小背包容量是等價的。
我們對 \(s_1\) 和 \(s_2\) 的大小進行分類討論。
設 \(s_1=m,s_2=m\) 容易發現這樣的合並不會超過 \(\frac{n}{m}\) 次,這是因為兩邊背包容量都等於 \(m\),說明有很多超過 \(m\) 個點被考慮進的背包內,因為我們的最終目標是把所有點合並成一個背包,而合並超過 \(m\) 個點的背包不超過 \(\frac{n}{m}\) 個,原命題得證。由此,這里的復雜度是 \(O(nm)\) 的。
設 \(s_1<m,s_2<m\) 設 \(s_1+s_2\ge m\) 這種情況下的合並次數不會超過 \(\frac{n}{m}\),因為這相當於把大小小於 \(m\) 的子樹全部合並,最壞情況是合並到不存在大小小於 \(m\) 的子樹,由大小大於等於 \(m\) 的子樹個數不會超過 \(\frac{n}{m}\) 可以知道合並次數不會超過 \(\frac{n}{m}\) 由此可知復雜度不會超過 \(O(nm)\)。
設 \(s_1<m,s_2<m\) 設 \(s_1+s_2< m\) 我們考慮一下 \(m\) 個點合並成為一棵大小為 \(m\) 的樹,總的復雜度應該為 \(m^2\),總共這樣的樹的個數不會超過 \(\frac{n}{m}\) 個,故最終的復雜度也應該為 \(O(nm)\)。由這段證明我們也可以得到所謂背包大小為 \(m\),實際上是一個限制,其標明整個樹形背包的復雜度不會超過 \(O(n^2)\),當然大多數情況下我們認為 \(m<n\)。
由此可以得出,樹上背包的復雜度為 \(O(nm)\)。
