經典揹包問題
01揹包和無限揹包略過
多重揹包的優化
這能優化到O(nm)?!
(我們以求方案數爲例)
設第i種物品有c[i]個,重量爲w[i]
f[i][j]=∑k=0c[i]f[i−1][j−k⋅w[i]]
這是最基本的暴力,然後考慮優化
我們寫一個類似前綴和的東西
設g[i][j]=f[i−1][j]+g[i−1][j−w[i]]
那麼f[i][j]=g[i][j]−g[i][j−(k[i]+1)⋅w[i]]
自此可以優化到O(nm)
Ps:若用二進制拆分來優化,就不能統計方案,比如說對於5會拆成{1,2,2},那麼再算選兩個時就會統計兩次。
小習題:
1. 考慮01揹包問題,有Q種操作,每次加入一種物品或刪除一種物品,每次操作完後輸出不超過S的方案數
n,Q,S≤2000
我們假設這個數重量爲w
對於加入這個數的操作:
for i:S downto wf[i]+=f[i−w]
對於刪除這個數的操作:
for i:w to Sf[i]−=f[i−w]
時間複雜度:O(nS)
2. 樹上依賴01揹包:如果兒子選了,則父親必須要選
這是一個很強的限制
思考後就會發現,這相當於在樹上選擇一個包含根節點的連通塊
那麼我們通過dfs序把原問題轉化到序列上
我們設f[i][1]表示選第i個點,f[i][0]表示不選第i個點
考慮f[i][1]的轉移 f[i][1]+=f[fa[i]][1]
考慮f[i][0]的轉移 f[i][0]+=f[ed[i]−1][0]
(未完待續)