01揹包問題簡單描述:
有乙個揹包和n個物品,揹包的承載量為c,每件物品重量為w[i],價值為v[i].問如何裝才能使揹包中物品的總價值最大?
解題方法:
f[i,j]:在前i個物品中選擇若干件放在承重為j的揹包中,可以取得的最大的價值。
f[i,j]=max(f[i-1,j-w[i]]+v[i] , f[i-1,j]);
決策:為了總價值最大化,第i件物品應該放入揹包中嗎?
int i,j,c=10;
int p[20]
[20];
for(i=0;i
<=c;i++)
p[0]
[i]=0;
for(i=1;i
<=n;i++)
else
p[i]
[j]=p[i-1]
[j];
}}
問題能深入:如何記錄哪些物品被選中了?
void output_sack(int p[20][20],int x[50],int w[50],int n,int c)
}x[1]=p[[1][c]?1:0;
}
解析:如果物品i沒有未選中則:p[i][j]=p[i-1][j]; 所以當p[i][j]==p[i-1][j]是說明第i個物品未被選中。當第i個物品選中後,c=c-w[i],說明第i個已經確定了(揹包空間考慮範圍減少w[i])。
優化(從二維陣列到一維陣列)
因為:f[i][j]取決於f[i-1][j]和f[i-1][j-w[i]]+v[i];
所以:f_i[j]取決於f_i-1[j]和f_i-1[j-w[i]]+v[i];(f[j]外套乙個for(i=1;i<=n;i++))
所以:可以用滾動的一維陣列;
for(int j=0;j
<=c;j++)
f[j]=0;
for(i=1;i
<=n;i++)
}
注意:由於f[j]有f[j]和f[j-w[i]]決定,即在二維陣列中的頭頂的乙個數和左邊的乙個數決定。所以要由c->0(確保左邊的乙個數是上一次迴圈的,即只能取一次),如果由0->c,左邊的值可能被改變了。
關於初始化的細節問題
沒有要求必須裝滿:初始化f[j]=0;
要求必須裝滿:初始化f[0]=0,f[j]=負無窮(j>=1)
01揹包問題詳解
n個物品,每個物品有乙個wi的重量和pi的價值,現在有乙個重w的揹包問放進物品後的最大值。首先是記憶化搜尋 dp i j 在前i件物品裡面選擇不超過重量j的最大價值 int rec int i,int j 基於上面的思想我們有遞推式dp i j 這樣的話時間複雜度和空間複雜度都是o nw 可以對空間...
0 1揹包問題詳解
網上好多關於揹包問題的解釋,自己也看了,感覺解釋的不容易通俗易懂,所以自己來寫乙個非常容易懂得。0 1揹包問題說的是,給定揹包容量w,一系列物品,每個物品只能取一件,獲取最大值。採用動態規劃求解,動態規劃的一般規律都是 在什麼什麼前i個狀態下的最大值或者最小值的前提下,然後再把i的狀態的值求出來。這...
揹包問題詳解(c ) 01揹包
有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i件物品的體積是 v,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。第一行兩個整數 n,v用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,每行兩個整數 vi,wi用空格...