2019金華Day18-dp專項

經典揹包問題

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章