0 1揹包問題

2021-08-18 18:33:51 字數 2671 閱讀 7736

另一種實現方法:

//動態規劃dp[i][j] 記錄 用j總容量去背起前i個揹包中的若干個揹包 的最大價值

//將用j總容量背起前i個揹包中若干個揹包的問題變為:背第i個揹包+用剩餘容量j-w[i]去背起前i-1個揹包中的若干個揹包.

//即dp[i][j]=v[i]+dp[i-1][j-w[i]];另外還有一種考慮不背第i個揹包的即為:dp[i][j]=dp[i-1][j];

//到此2種情況要判斷取最大,故得出狀態轉移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

//可見求前i個揹包用j容量的最大價值需要先知道dp[i-1][j]和dp[i-1][j-w[i]]這2個值已經在計算i的前算出.

#include

#include

#include

#include

#include

using namespace std;

int n,c;

int w[20],v[20];

int m[20][20];

int dp[20][20];

int x[20];

void traceback()

x[1]=dp[1][c]>0?1:0;

}int main()

printf("%d\n",dp[n][c]);

traceback();

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

printf("%d ",x[i]);

cout

3 54 7

3 52 3

*/

空間上優化後:

(這個貌似不能算出將哪個包放進了)

#include

#include

#include

#include

#include

using

namespace

std;

int n,c;

int w[20],v[20];

int m[20][20];

int dp[20];

int main()

printf("%d\n",dp[c]);

cout

/*3 5

4 73 5

2 3*/

// 01 揹包

#include

#include

using

namespace

std;

int dp[21][1010];

int w[21],c[21];

int main()

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

cout

/*5 10

2 13 5

2 53 4

4 3*/

空間優化正如我們上面所說,f[v-c[i]]就相當於原來f[i-1][v-c[i]]的狀態。如果將v的迴圈順序由逆序改為順序的話,就不是01揹包了,就變成完全揹包了,這個後面說。這裡舉乙個例子理解為何順序就不是01揹包了

假設有物體z容量2,價值vz很大,揹包容量為5,如果v的迴圈順序不是逆序,那麼外層迴圈跑到物體z時,內迴圈在v=2時,物體z被放入揹包,當v=4時,尋求最大價值,物體z放入揹包,f[4]=max,這裡毫無疑問後者最大,那麼此時f[2]+vz中的f[2]已經裝入了一次物體z,這樣一來該物體被裝入揹包兩次了就,不符合要求,如果逆序迴圈v,這一問題便解決了。

// 01 揹包

#include

#include

using

namespace

std;

int dp[1005];

int w[105],c[105];

int main()

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

}cout

/*5 10

2 13 5

2 53 4

4 3*/

揹包問題 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...