01 背包问题和完全背包
Problem Description
一个旅行者有一个最多能用m公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn.若每种物品只有一件求旅行者能获得最大总价值。Input
输入的第一行为T,表示测试数据的组数。对于每组测试数据的第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30),第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。Output
对于每组测试数据输出仅一行,一个数,表示最大总价值。Sample Input
1 10 4 2 1 3 3 4 5 7 9
Sample Output
12
【代码】
#include<iostream>
#include<cstdio>
using namespace std;
int w[20],v[20],f[20];
int main()
{
int m,n;
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&w[i],&v[i]);
for(int i=1;i<=n;i++)
{
for(int j=m;j>=w[i];j--)
{
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
printf("%d",f[m]);
return 0;
}
//判断和不判断的差别 /*12 1 1 1 1 1 1 1 1 1 0 4 4 4 4 4 4 3 3 1 0 9 9 8 8 6 5 5 3 1 0 12 10 9 9 6 5 5 3 1 0 */ /* 14 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 3 3 3 9 9 9 8 8 8 5 5 5 5 14 14 14 9 9 9 9 9 9 9 */
//每一件物品的状态抉择为放还是不放 如果不放 前i件物品 不超过v的最大值就是前i-1件物品不超过v的最大值
否则 放就是 前i-1物品放入 v-w[i]的最大值加上要放入的当前的价值
优化 二维数组优化为一维数组 f[v]为重量不超过v的最大值
【代码】
#include<iostream> #include<cstdio> using namespace std; int w[20],c[20],f[20][20]; int main() { int m,n; scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]); for(int i=1;i<=n;i++) { for(int v=m;v>0;v--) { if(w[i]<=v)//必须要判断 f[i][v]=max(f[i-1][v],f[i-1][v-w[i]]+c[i]); else f[i][v]=f[i-1][v]; } } printf("%d",f [m]); return 0; }
完全背包
【代码】
二维
#include<iostream> #include<cstdio> using namespace std; int w[20],f[20][20],c[30]; int main() { int m,n; scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(w[i]>j) f[i][j]=f[i-1][j]; else if(f[i-1][j]>f[i-1][j-w[i]]+c[i]) f[i][j]=f[i-1][j]; else f[i][j]=f[i-1][j-w[i]]+c[i]; } } printf("%d",f [m]); return 0; }
一维
#include<iostream> #include<cstdio> using namespace std; int f[20],w[20],c[20]; int main() { int m,n; scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]); for(int i=1;i<=n;i++) { for(int j=w[i];j<=m;j++) { if(f[j]<f[j-w[i]]+c[i]) f[j]=f[j-w[i]]+c[i]; } } printf("%d",f[m]); return 0; }
数据 其实没多大用这数据。。。。
12(二维) 0 1 1 1 1 1 1 1 1 1 0 1 3 3 4 4 4 4 4 4 0 1 3 5 5 6 8 8 9 9 0 1 3 5 5 6 9 9 10 12 12(一维) 0 1 3 5 5 6 9 10 10 12
01背包和完全背包的区别是完全背包每种物品有无数件 所以每次决策就改变了 不在是取或不取 而是取几件、
分析一下代码 发现两个代码很像 区别就是01背包体积循环是 v--1,而完全背包是1--v
why?
为什么01逆序 完全顺序
先讲01如果顺序后会怎样呢?
我们知道f[v]=max(f[v],f[v-w[i]]+c[i]);如果顺序1--v,因为f[v]是由f[v-w[i]]推过来的,如果顺序的话 f[v-w[i]]一定推完了 我们可能在f[v-w[i]]时就已经
放入了i物品 ,所以你推的f[v]就拿了两件i物品了,所以01要逆推,,,反之,,拿好几件就是完全 顺推了。。。。
我也刚懂。。。糊里糊涂的。。。自己好好想想吧QAQ
- 背包问题(01背包,完全背包,多重背包)
- 背包问题(01背包,完全背包,多重背包)
- 01背包,完全背包,多重背包问题详细介绍以及源代码实现
- 背包问题之01背包、完全背包和多重背包
- 背包问题:01背包/完全背包
- 背包问题(01背包,完全背包,多重背包)
- DP背包问题小结(01背包,完全背包,需恰好装满或不需,一维DP、二维DP)
- 背包问题【01、完全(恰好or不超过)、多重】【尚未整理完】
- 背包问题教程-01背包,完全背包,多重背包,混合背包
- 夕拾算法进阶篇:17)01背包和完全背包问题 (动态规划DP)
- 背包(01背包、完全背包、多重背包)问题总结
- 背包问题总结(01背包、完全背包、多重背包)
- 01背包 完全背包问题
- 经典问题之01与完全背包总结
- 01背包、完全背包、多重背包、混合三种背包问题
- 01背包问题和完全背包问题,一个不理解的关键。
- 01背包问题和完全背包问题
- 01背包问题和完全背包问题
- 四种背包问题(01和完全)
- 01背包、完全背包、多重背包问题分析