完全揹包問題

2021-08-21 15:46:52 字數 1366 閱讀 4755

完全揹包和01揹包的區別在於完全揹包每一件物品的數量都有無限個,而01揹包每件物品數量只有1個

狀態轉移方程:

dp[i][j] = max(dp[i-1][j],dp[i][j-a[i]]+v[i])

or dp[j] = max(dp[j],dp[j-a[i]]+v[i])

如果不放那麼f[i][j]=f[i-1][j];如果確定放,那麼當前揹包中應該出現至少一件第i種物品,所以f[i][j]中至少應該出現一件第i種物品,即f[i][j]=f[i][j-c[i]]+w[i],為什麼會是f[i][j-c[i]]+w[i]?

因為我們要把當前物品i放入包內,因為物品i可以無限使用,所以要用f[i][j-c[i]];如果我們用的是f[i-1][j-c[i]],f[i-1][j-c[i]]的意思是說,我們只有一件當前物品i,所以我們在放入物品i的時候需要考慮到第i-1個物品的價值(f[i-1][j-c[i]]);但是現在我們有無限件當前物品i,我們不用再考慮第i-1個物品了,我們所要考慮的是在當前容量下是否再裝入乙個物品i,而[j-c[i]]的意思是指要確保f[i][j]至少有一件第i件物品,所以要預留c[i]的空間來存放一件第i種物品。總而言之,如果放當前物品i的話,它的狀態就是它自己"i",而不是上乙個"i-1"。

public static int back(int a,int v,int m)

}return dp[a.length][m];

}

我們可以繼續優化此演算法,可以用一維陣列寫

我們用f[j]表示當前可用體積j的價值,我們可以得到和01揹包一樣的遞推式:

dp[j] = max(dp[j],dp[j-a[i]]+v[i])
先貼出**

public static int back(int a,int v,int m){

int dp = new int[m+1];

for(int i = 0 ; i 對於01揹包來說,是逆序,裝不裝當前物品i取決於第i-1個物品(f[i]只和f[i-1]有關);而對於完全揹包來說,裝不裝物品取決於他前乙個物品i(因為可以放無數個物品i),因為當前物品i是無限的不用去考慮f[i-1],而應當考慮當前狀態下是否應當再裝入當前乙個物品i。或者換一種說法:完全揹包考慮的是第i種物品的出現的問題(該不該放入當前物品i),第i種物品一旦出現它勢必應該對第i種物品還沒出現的各狀態造成影響,也就是說,原來沒有第i種物品的情況下可能有乙個最優解,現在第i種物品出現了,而它的加入有可能得到更優解,所以之前的狀態需要進行改變,故需要正序。

也就是說完全揹包是說,在當前體積下,是否要放入或者再放入乙個當前物品i,而01揹包是說,在當前體積下,是否要放入乙個當前物品i

揹包問題(完全揹包)

1.矩陣鏈乘法 2.投資組合問題 3.完全揹包問題 4.01揹包問題 5.最長公共子串行 乙個揹包,可以放入n種物品,物品j的重量和價值分別為,如果揹包的最大重量限制是b,怎麼樣選擇放入揹包的物品以使得揹包的總價值最大?組合優化問題,設表示裝入揹包的第j個物品的數量,解可以表示為。那麼目標函式和約束...

完全揹包問題

這個是從ppt上弄過來的。完全揹包問題 有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。放入第i種物品的耗費的空間是ci,得到的價值是wi。求解 將哪些物品裝入揹包,可使這些物品的耗費的空間總和不超過揹包容量,且價值總和最大 基本思路 這個問題非常類似於01揹包問題,所不同的是每種物品有無限...

完全揹包問題

設有n種物品,每種物品有乙個重量及乙個價值。但每種物品的數量是無限的,同時有乙個揹包,最大載重量為m,今從n種物品中選取若干件 用乙個物品可以多次選取 使其重量的和小於等於m,而價值的和為最大。輸入有多組資料,對於每組輸入資料第1行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 第2...