讀書筆記 0 1揹包相關問題

2022-08-31 04:15:08 字數 3429 閱讀 6259

/*

*0-1 揹包問題:經典動態規劃入門題

記憶化搜尋方法:靜態記錄下遞迴過程中的狀態值,避免重複計算

在 n 個重量和價值分別是 wi 和 vi 的物品中挑選,使得物品重量總和

不超過 w, 並且讓其價值總和盡量大

問題規模:

1 <= n <= 100

1 <= wi,vi <= 100

1 <= w <= 10000

狀態轉移方程:

dp(i,s) = dp(i - 1, s - w[i]) + v[i]; // s - w[i] >= 0

*/#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxw = 10000 + 5

;const

int n = 100 + 5

;int

n,w;

intw[n],v[n];

intd[n][maxw];

int dp(int i, int

s)void

solve()

intmain()

/*

*0-1 揹包問題:經典動態規劃入門題

在 n 個重量和價值分別是 wi 和 vi 的物品中挑選,使得物品重量總和

不超過 w, 並且讓其價值總和盡量大

問題規模:

1 <= n <= 100

1 <= wi,vi <= 100

1 <= w <= 10000

狀態轉移方程:

dp[i][j] = dp[i-1][j-w[i]] + v[i]; // j - w[i] >= 0

*/#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxw = 10000 + 5

;const

int n = 100 + 5

;int

n,w;

intw[n],v[n];

intdp[n][maxw];

void

solve()

}printf(

"%d\n

", dp[n][w]);

}int

main()

/*

*在 n 種重量和價值分別是 wi 和 vi 的物品中挑選,使得物品重量總和

不超過 w, 並且讓其價值總和盡量大

問題規模:

1 <= n <= 100

1 <= wi,vi <= 100

1 <= w <= 10000

0-1揹包:每種物品只有乙個

狀態轉移方程:dp[i][j] = max(dp[i-1][j] ,dp[i-1][j-w[i]]+v[i]);

0-1揹包的狀態更新只跟上一層的考慮有關係

完全揹包:每種物品有無數個

狀態轉移方程:dp[i][j] = max(dp[i-1][j],dp[i][j-w[i]]+v[i]);

完全揹包在本層中,需要考慮 對選擇過本層物品後更新的狀態 的使用,

所以在實現上有所差別

*/#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxw = 10000 + 5

;const

int n = 100 + 5

;int

n,w;

intw[n],v[n];

intdp[maxw];/**

都使用一維陣列來寫

*/void

solve_01()

}printf(

"%d\n

", dp[n][w]);

}void

solve_entire()

}printf(

"%d\n

", dp[n][w]);

}int

main()

/*

*在 n 個重量和價值分別是 wi 和 vi 的物品中挑選,使得物品重量總和

不超過 w, 並且讓其價值總和盡量大

問題規模:

1 <= n <= 100

1 <= vi <= 100

1 <= wi <= 1e7

1 <= w <= 1e9

這題的重量的數量級比普通的揹包擴大了10000倍,所以再使用之前的演算法

列舉重量狀態o(n*w),次數量到達1e11,這將不是1s可以跑出來的方法。

所以改變策略,狀態描述為dp[i][j],考慮前i個物品價值總和為j的最小重量,

狀態轉移方程:

dp[i][j] = min(dp[i-1][j], dp[i-1][j-v[i]]+w[i]);

然後從所有的價值狀態中,找到重量合法的最大價值

*/#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxw = 1e9 + 5

;const

int maxv = 1e5 + 5

;const

int n = 100 + 5

;int

n,w;

intw[n],v[n];

intdp[n][maxv];

void

solve_entire()

memset(d,

0x3f, sizeof

(d));

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

}int ans =maxv;

for(int i = maxv; i >= 0; i--)

}printf(

"%d\n

", ans);

}int

main()

01揹包 完全揹包以及相關問題

有n件物品和乙個容量為v的揹包。第i件物品的體積是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。從這個題目中可以看出,01揹包的特點就是 每種物品僅有一件,可以選擇放或不放。其狀態轉移方程為 f i v max 表示在揹包剩餘容量為v,面對第i個物品決策時,可以獲得的最大價值總和 p...

揹包問題九講筆記 01揹包問題

有 n 件物品和乙個容量為 v的揹包 放入第 i 件物品 放入第 i件物品耗費的容量是ci 所獲得的價值是wi 每件物品只有乙個 求將哪些物品放入揹包可使價值總和最大 一般來說求極值的問題可分為貪心,動態規劃,以及遍歷所有可能 在這三中方法中,動態規劃是最常見的,也是很難想出來的 其中最難的是定義子...

揹包問題 01揹包問題

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