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