01揹包問題

2021-08-07 01:17:49 字數 2363 閱讀 3800

問題描述:

有n件物品,它們的重量分別是w1,w2,w3...wn,他們的價值分別是c1,c2,c3...cn,現有乙個m容量的揹包,選擇n件物品裝入揹包,求能裝入揹包的最大價值。

01揹包是最基本的揹包問題,特點是:每一種物品只有一件,可以選擇放入揹包或者不放揹包。(也是決策)

通常,狀態可以根據問題所求來得出,題目求n件物品放入容量m的揹包可以獲得的最大價值,可以轉換為前i件物品放入j容量的揹包的最大價值的子問題。

因此,設f[i][j]表示前i件物品放入容量為j的揹包的最大價值。則狀態轉移方程就是:

f[i][j]=max.

如何理解f[i-1][j],和f[i-1][j-w[i]]+c[i]?

前i-1個物品已經放入了容量j的揹包中,第i件物品就有兩種選擇,放或者不放。

f[i-1][j]表示第i件物品不放入揹包中f,[i][j]=f[i-1][j]:

不放入有兩種情況,一是揹包容量不夠(例如揹包容量為5,第i件物品的重量為7,選擇不放入)

二是放入第i件物品揹包的價值小於不放入的價值,選擇不放入(例如揹包容量為8,第一件c1=6,w1=10,第二件c2=7,w2=8...第i件ci=8,wi=9,選擇放入第一件,不放入第i件)

f[i-1][j-w[i]]+c[i]表示第i件物品放入揹包中,f[i][j]=f[i-1][j-w[i]]+c[i]:

所以最大價值就是沒放入之前的最大價值f[i-1][j-w[i]],加上放入第i件物品的價值c[i],即f[i-1][j-w[i]]+c[i]

總共兩種情況,要求最大值,就選擇兩者中最大的乙個,即:f[i][j]=max

f[i][j]表示前i件物品放入容量j揹包的最大值,因此i的範圍0-n,j的範圍為0-m.

#includeusing namespace std;

int f[550][550],w[550],c[550];

int main()

} cout<

使用二維陣列f[n][m]時,當n或者m太大,空間會超出限制。其實,也可以用一維陣列來進行求解。

用f[j]表示容量j的能裝的最大價值。

同理,f[j]=max

#includeusing namespace std;

int f[550],w[550],c[550];

int main()

} cout《為什麼必須要逆序呢?

假設揹包容量是m=10

三件物品

w1=5,c1=20

w2=6,c2=10

w3=4,c3=12

當i=1:

f[10]=max=20

f[9]=max=20

f[8]=max=20

f[7]=max=20

f[6]=max=20

f[5]=max=20j1

2345

6789

10f[j]00

002020

2020

2020

當i=2:

f[10]=max=20

f[9]=max=20

f[8]=max=20

f[7]=max=20

f[6]=max=20j1

2345

6789

10f[j]00

002020

2020

2020

當i=3:

f[10]=max=32

f[9]=max=32

f[8]=max=20

f[7]=max=20

f[6]=max=20

f[5]=max=20

f[4]=max=12j1

2345

6789

10f[j]00

0122020

2020

3232

f[10]就是揹包容量最大時的最大值,容量大的值取決於容量小的值,不斷更新容量大的值,所以必須逆序。

如果順序,乙個物品就可能被放入多次。

用同樣的例子可以分析:

for(int i=1;i<=n;i++)

}

當i=1;

f[5]=max=20

f[6]=max=20

f[7]=max=20

f[8]=max=20

f[9]=max=20

f[10]=max=40j1

2345

6789

10f[j]00

002020

2020

2040

可以看出問題來了,f[10]=f[5]+20=40,相當於第一件物品拿了兩次,顯然不符合題意。

因此,必須逆序。 

 





揹包問題 01揹包問題

n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...

揹包問題 01揹包

有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...

揹包問題(01揹包)

1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...