Problem Description
Input
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[n][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[n][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