背包问题
0-1背包:每种物品只有一件,每次选择放入或不放入,最终得到固定的承重可以得到的最大价值。
核心思想:分割成子背包,首先等于背包大小,求子背包的最大价值,直到子背包的大小到物品大小。
在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。
其中1 <= N <= 100,1 <= W <= 10000,每个物品1 <= Wi, Pi <= 10000。
输入
第1行输入两个整数N和W;
第2 ~ N+1行,每行两个整数Wi和Pi,分别表示每个物品的体积和价值。
输出
输出可以容纳的最大价值。
输入样例
3 6
2 5
3 8
4 9
输出样例
14
代码:
#include <iostream> #include <cstring> using namespace std; int ans[10000]; //求子背包能装的最大值 int w[100], v[100]; void dp(int w, int v, int c) { //物品大小,物品价值,背包大小。 dp装入背包的价值为最大值 for (int i = c; i >= w; i--) { //从最大子背包开始装入,使每件物品只装一次 ans[i] = max(ans[i], ans[i - w] + v); //求子背包最大价值 } } int main() { int n, c; cin >> n >> c; //输入物品种类,背包大小 memset(ans, 0, sizeof(ans)); //初始化子背包 for (int i = 0; i < n; i++) { cin >> w[i] >> v[i]; //输入物品大小,价值 } for (int i = 0; i < n; i++) { //循环放入物品的大小,价值 dp(w[i], v[i], c); } cout << ans[c] << endl; //输出ans[c]表示大小为C的子背包能装的最大价值 }
完全背包:每件物品数量不限,求限定容量的最大价值。
核心思想:分割成子背包,首先等于物品大小,求子背包最大价值,直到子背包大小到背包大小。
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是v[i],价值是c[i]。
现在请你选取一些物品装入背包,使这些物品的体积总和不超过背包容量,且价值总和最大。
其中1<=N<=100,1<=V<=50000,1<=v[i],c[i]<=10000。
输入
第一行输入两个数N,V,分别表示物品种类数和背包容积;
之后N行,每行两个数v[i],c[i],分别表示第i种物品的体积和价值;
输出
输出一个数表示最大的价值
输入样例
2 11
2 3
6 4
输出样例
20
代码:
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 int ans[50055]; 8 int w[105], v[105]; 9 10 void dp(int n, int c) { 11 for (int j = 1; j <= n; j++) { //物品循环放入 12 for (int i = w[j]; i <= c; i++) { //从最小大小物品开始装入背包 13 ans[i] = max(ans[i], ans[i - w[j]] + v[j]); //求子背包最大价值 14 } 15 } 16 } 17 18 int main() { 19 int n, c; 20 cin >> n >> c; //输入物品种类,背包大小 21 memset(ans, 0, sizeof(ans)); 22 for (int i = 1; i <= n; i++) { 23 cin >> w[i] >> v[i]; //输入物品大小,价值 24 } 25 dp(n, c); // dp背包 26 cout << ans[c] << endl; //输出ans[c]表示大小为C的子背包能装的最大价值 27 }
浙公网安备 33010602011771号