完全揹包問題

2021-10-08 15:11:20 字數 1400 閱讀 2595

完全揹包問題與01揹包的概念大體相同,二者最大的不同是:01揹包問題中每件物品的個數只有乙個,而在完全揹包中物品的個數是無限個。也就是說我們在選擇物品時,同一種物品我們可以多次選擇以得到最優解。

首先我們還是定義乙個dp[i][j]陣列用來記錄狀態,i表示第幾件物品,j表示揹包的容量。同樣我們也分為兩種情況:

不放入第i件物品,也就是dp[i-1][j]這與01揹包相同。

我們選擇放入第i件物品,這種情況下兩種揹包問題就不同之處了,01揹包的狀態方程是:

dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])
而完全揹包的狀態方程是:

dp[i][j] = max(dp[i-1][j],dp[i][j-w[i]]+v[i])
不同之處在於後面乙個是dp[i-1],乙個是dp[i]。因為完全揹包中每種物品有無限個,我們放入過這種物品後還可以繼續放入這種物品,所以他的狀態是由他自己這種物品轉移過來,而不是從上一種物品轉移,所以是dp[i]。

與01揹包類似,我們也可以對上面的狀態方程進行空間優化。不同的是01揹包中是反向列舉,而完全揹包是正向列舉。因為01揹包中狀態來自上一種物品,我們要避免上一層被覆蓋,完全揹包中狀態來自同種物品,我們需要覆蓋。

直接上**

for

(int i=

1;i<=n;i++

)}

我們從第i件物品放多少件出發,01揹包只有放0件和放1件,而這裡是0件,1件…直到超過限重(k>j/w[i]),我們可以推出狀態方程:

dp[i][j] = max(dp[i-1][j],dp[j-k*w[i]]+k*v[i])//k為裝入第i種物品的件數
這種方法我們也可以進行空間優化:

for

(int i=

1;i<=n;i++

)//物品

}}

#include 

#include

#include

using namespace std;

int w[

510]

,v[510

],dp[

50010];

int main()

}if(dp[m]

==100000000

) cout<<

"this is impossible."

cout<<

"the minimum amount of money in the piggy-bank is "

<<<

"."<}return0;

}

揹包問題(完全揹包)

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...