之前我們已經介紹了0/1揹包問題,現在我們以洛谷p1616為例,介紹一下完全揹包問題
完全揹包問題就是將0/1揹包問題中的每樣物品只能拿一次這個限制條件去掉,每樣物品可以無限次裝入。
對於完全揹包的圖形解釋,我擷取《leetcode_101》內的解釋展現出來:
簡要說一下推導過程:因為我們可以多次拿取物品,在總容積不超過j的情況下,我們也最多只能裝j/v[i]=k個物品,那麼狀態轉移方程就寫為
dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i],dp[i-1][j-2*v[i]]+2w[i],...dp[i-1][j-k*v[i]])。
利用0/1揹包思想,我們可以得到
dp[i][j-v]=max( dp[i-1][j-v] , dp[i-1][j-2v]+w[i],dp[i-1][j-3v]+2w[i], dp[i-1][j-4v]+3w[i],..., dp[i-1][j-kv]+(k-1)w[i])。兩邊同時加上w[i]後可以替換上式中的max(dp[i-1][j-v[i]]+w[i],dp[i-1][j-2*v[i]]+2w[i],...dp[i-1][j-k*v[i]]).
所以我們就得到了狀態轉移方程——dp[i][j]=max(dp[i-1][j],dp[i][j-v[i]]+w[i])
同樣的,我們可以對上述dp陣列進行狀態壓縮,將第乙個維度去掉。思路與0/1揹包問題基本一致。
壓縮後的狀態轉移方程:
dp[j]=max(dp[j],dp[j-w[i]]+w[i])
**可寫為:
for(int i=0;i注意此時我們這裡與0/1揹包問題不同,此時我們是正向遍歷陣列。因為我們需要利用到j-w[i]列的資訊。注意此時右邊的dp[j]是第i-1行的值。
因此,介紹完完全揹包問題後,洛谷的這道程式設計題就十分容易了:
揹包問題(二) 完全揹包問題
繼0 1揹包問題後,本文介紹完全揹包問題 0 1揹包問題見 完全揹包問題與01揹包問題的區別在於每一件物品的數量都有無限個,而01揹包每件物品數量只有乙個。問題解法其實和01揹包問題一樣,只是初始化的值和遞推公式需要稍微變化一下。初始化時,當只考慮一件物品a時,f 1 j j weight a 遞推...
揹包問題(完全揹包)
1.矩陣鏈乘法 2.投資組合問題 3.完全揹包問題 4.01揹包問題 5.最長公共子串行 乙個揹包,可以放入n種物品,物品j的重量和價值分別為,如果揹包的最大重量限制是b,怎麼樣選擇放入揹包的物品以使得揹包的總價值最大?組合優化問題,設表示裝入揹包的第j個物品的數量,解可以表示為。那麼目標函式和約束...
揹包問題(0 1揹包 完全揹包)
0 1揹包 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。重要的點在於 每種物品僅有一件,可以選擇放 不放子問題 f i v 表示前i件物品恰好放入乙個 容量為v 的揹包可以獲得的最大價值。狀態轉移方程 遞推式 f i v max 考...