有依赖的背包问题(背包九讲)
問題:
這樣的背包問題的物品間存在某種“依賴”的關系。也就是說,i依賴于j,表示若選物品i,則必須選物品j。為了簡化起見,我們先設沒有某個物品既依賴于別的物品,又被別的物品所依賴;另外,沒有某件物品同一時候依賴多件物品。
算法:
這個問題由NOIP2006金明的預算方案一題擴展而來。遵從該題的提法,將不依賴于別的物品的物品稱為“主件”,依賴于某主件的物品稱為“附件”。由這個問題的簡化條件可知全部的物品由若干主件和依賴于每一個主件的一個附件集合組成。依照背包問題的一般思路,僅考慮一個主件和它的附件集合。但是,可用的策略許多,包含:一個也不選,僅選擇主件,選擇主件后再選擇一個附件,選擇 主件后再選擇兩個附件……無法用狀態轉移方程來表示如此多的策略。(其實,設有n個附件,則策略有2^n+1個,為指數級。)考慮到全部這些策略都是相互排斥的(也就是說,你只能選擇一種策略),所以一個主件和它的附件集合實際上相應于P06中的一個物品組,每一個選擇了主件又選擇了若干個附件的策略相應于這個物品組中的一個物品,其費用和價值都是這個策略中的物品的值的和。但不過這一步轉化并不能給出一個好的算法,由于物品組中的物品還是像原問題的策略一樣多。再考慮P06中的一句話:能夠對每組中的物品應用P02中“一個簡單有效的優化”。
這提示我們,對于一個物品組中的物品,全部費用同樣的物品僅僅留一個價值最大的,不影響結果。所以,我們能夠對主件i的“附件集合”先進行一次01背包,得到費用依次為0..V-c[i]全部這些值時對應的最大價值f'[0..V-c[i]]。那么這個主件及它的附件集合相當于V-c[i]+1個物品的物品 組,當中費用為c[i]+k的物品的價值為f'[k]+w[i]。也就是說原來指數級的策略中有非常多策略都是冗余的,通過一次01背包后,將主件i轉化為 V-c[i]+1個物品的物品組,就能夠直接應用P06的算法解決這個問題了。
較一般的問題:
更一般的問題是:依賴關系以圖論中“森林”的形式給出(森林即多叉樹的集合),也就是說,主件的附件仍然能夠具有自己的附件集合,限制僅僅是每一個物品最多僅僅依賴于一個物品(僅僅有一個主件)且不出現循環依賴。解決問題仍然能夠用將每一個主件及其附件集合轉化為物品組的方式。唯一不同的是,因為附件可能還有附件,就不能將每一個附件都看作一個一般的01背 包中的物品了。若這個附件也有附件集合,則它必然要被先轉化為物品組,然后用分組的背包問題解出主件及其附件集合所相應的附件組中各個費用的附件所相應的價值。其實,這是一種樹形DP,其特點是每一個父節點都須要對它的各個兒子的屬性進行一次DP以求得自己的相關屬性。這已經觸及到了“泛化物品”的思想??赐關08后,你會發現這個“依賴關系樹”每一個子樹都等價于一件泛化物品,求某節點為根的子樹相應的泛化物品相當于求其全部兒子的相應的泛化物品之和。
小結:
NOIP2006的那道背包問題我做得非常失敗,寫了上百行的代碼,卻一分未得。后來我通過思考發現通過引入“物品組” 和“依賴”的概念能夠加深對這題的理解,還能夠解決它的推廣問題。用物品組的思想考慮那題中極其特殊的依賴關系:物品不能既作主件又作附件,每一個主件最多 有兩個附件,能夠發現一個主件和它的兩個附件等價于一個由四個物品組成的物品組,這便揭示了問題的某種本質。
我想說:失敗不是什么丟人的事情,從失敗中全無收獲才是。
--------------------------------------------------------------------------------------
練習:
---------------------------------------------------------------------------------------
總結:
這是一種樹形DP,其特點是每一個父節點都須要對它的各個兒子的屬性進行一次DP以求得自己的相關屬性。通過一次01背包,把物品轉化為幾組物品,用分組背包的方法求解。(dfs每一個根結點)
總結
以上是生活随笔為你收集整理的有依赖的背包问题(背包九讲)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AIGC疯狂一夜!英伟达投下“核弹”、G
- 下一篇: android震动提示音,android