01揹包問題詳解

2021-07-10 05:31:28 字數 1327 閱讀 6814

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用空格...