DP之完全揹包問題

2021-08-18 13:08:38 字數 1422 閱讀 7390

such as

:設有n種物品,每種物品有乙個重量及乙個價值。但每種物品的數量是無限的,同時有乙個揹包,最大載重量為m,今從n種物品中選取若干件(同一種物品可以多次選取

),使其重量的和小於等於m,而價值的和為最大。

對於這個問題,啊,還是直接上**吧,在**中理解,

解一:只需在01揹包上稍稍改善以下就行

#include#include#includeusing namespace std;

int main()

; ///為便於讀者閱讀,初始化

int w=;

int n=6,c=12;

for(int i=1;i<=n;i++) ///從第1個到第i個物品中挑選出總重量不超過j的物品時總價值的最大值}}

printf("%d\n",dp[n][c]); ///總價值

return 0;

}

解二:

這樣寫的的程式有三重迴圈,顯然複雜度有點大哦,其實我們還可以優化,怎麼優化呢?看這裡,我們在

dp[i][j]

的計算中選擇k(k>=1)個的情況,與在dp[i+1][j-w[i]]的計算中選擇k-1個的情況是一樣的,,這樣我們就不需要k變數迴圈語句了,所以我們就可以這樣敲:

dp[i]

[j]=max(dp

[i-1]

[j],dp

[i][j-w[i]]+v[i]); 

k-1個

dp[i]

[j-w[i]]=max(dp

[i-1]

[j],dp

[i][j-2*w[i]]+2*v[i]);    k-2個

;此次其實已經

在k-1個之前算出來了(

因為j是從1到c的,k-2個的j-2*w[i]值是不是肯定小於k-1個的j-w[i]的值,所以就能很好的解釋為什麼k-2個在k-1個之前已經算出來了

),我們就是通過這樣類似於解法1的迴圈去解出來的,緊接著還有k-3個,也在k-2個之前已經求出來了,以此類推,直到k-n==1

次結束。自己細想下就能明白的。

#include#include#includeusing namespace std;

int main()

; ///為便於讀者閱讀,初始化

int w=;

int n=6,c=12;

for(int i=1;i<=n;i++) ///從第1個到第i個物品中挑選出總重量不超過j的物品時總價值的最大值

{for(int j=1;j<=c;j++)

{///此句與01揹包中dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

///有區別哦,注意比較理解

if(j

揹包問題之完全揹包

完全揹包 有n種物品,每種物品有無限個,每個物品的重量為w i 價值為v i 現在有乙個揹包,它所能容納的重量為c,問 你的揹包所能帶走的最大價值是多少?之前01揹包分析過了,如果是順序的話,就表示同一物品可以多次放入!這就是完全揹包!就是這麼神奇!1 include 2 3using namesp...

完全揹包問題講解(dp)

此題之前先分析兩種常見的揹包問題,01揹包與完全揹包 01揹包 在m件物品中取出若干件物品放到揹包中,每件物品對應的體積v1,v2,v3,對應的價值為w1,w2,w3,每件物品之多拿一件。解決方案 考慮用動態規劃的方法來解決,這裡的 階段是 在前n件物品中,選取若干件物品放入揹包中 狀態是 在前n件...

DP學習之完全揹包

有 n nn 種物品和乙個容量是 v 的揹包,每種物品都有無限件可用。第 i ii 種物品的體積是v iv i vi 價值是 w iw i wi 求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。資料範圍 0 v 1000 00v 10 000 wi 1000 00 wi 1...