有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 qi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
存入一个之后进行比较一轮
4 5
1 2
2 4
3 4
4 5
如这个例题
一开始
背包容量 0 1 2 3 4 5
物品价值 0 0 0 0 0 0
有四件物品,容量是五
此时存入第一个物品,体积是1 价值是2
此时背包大小从1到5都可以存
背包容量 0 1 2 3 4 5
物品价值 0 2 2 2 2 2
此时存入第二个物品,体积是2 价值是4
此时背包大小从2到5都可以存
于是可以进行比较
注意!(下面为错误情况)要从后往前比较,从前往后的话会有问题比如说下面情况
对于容量是2的情况,之前已经存了一个价值2,体积1的
假设现在不存这个体积1,价值2的,存了第二个物品,它体积是2,价值是4
比较一下 4大于2,所以容量为2的背包现在最多存4价值的物品,以此类推
容量为3时候,存入一个体积2的价值4的之后,还可以继续存一个单位,于是找到
容量为1的背包,这是容量1的最大价值,所以最后背包3价值为6,但是这样下去
背包容量 0 1 2 3 4 5
物品价值 0 2 4 6 8 10
下面是正确情况
一开始背包容量 0 1 2 3 4 5
一开始物品价值 0 2 2 2 2 2
存第二个物品,它体积是2,价值是4对背包5进行比较
容量为5的背包现在存了4价值的物品,还剩下3个体积,此时加上容量为3的背包的价值
一共是价值为6,大于原先的2,所以现在5号背包最大价值为6
背包容量 0 1 2 3 4 5
物品价值 0 2 4 6 6 6
代码:
s数组是背包总价值
for(int i=1;i<=n;i++){
cin>>q>>w; //输入体积和价值
for(int j=m;j>=q;j--){ //从后往前推
if(s[j]<s[j-q]+w){ //比较加入这次物品和不加的价值
s[j]=s[j-q]+w; //如果加入之后更大,那就把总价值变成加入后的
}
}
}
cout<<s[m]; //输出背包m,就是最大体积的背包价值