多重背包问题描述及其代码
在01背包的基础上,01背包是每个物品有一个,所以只能放入一次,此时我们再加入一个物品个数的数组s
,表示每个物品的个数,多重背包介于01背包和完全背包中间,加入了判断物品个数的一个维度,我们可以在01背包基础上,增改下代码(这里面我们直接上一维数组的了,不讲空间优化了,有兴趣的可以去看前面写过的背包问题,已经写过了):
/**
* @param V 最大容量
* @param C 物品个数
* @param v 价值数组
* @param w 重量数组
* @param s 物品个数
* @return
*/
public int getMaxValueWithLimitNums(int V, int C, int[] v, int[] w, int[] s) {
int[] dp = new int[V + 1];
for (int i = 0; i < C; i++) { //遍历物品
for (int fv = V; fv >= w[i]; fv--) { //遍历重量
for (int n = 1; n <= s[i] && fv - n * w[i] >= 0; n++) {
dp[fv] = Math.max(dp[fv], dp[fv - n * w[i]] + n * v[i]);
}
}
}
return dp[V];
}
@Test
public void testgetMaxValueWithLimitNums() {
int V = 5;
int C = 2;
int[] v = {1, 2};
int[] w = {1, 2};
int[] s = {2, 1};
System.out.println(getMaxValueWithLimitNums(V, C, v, w, s)); //4
}
与01背包不同的是,代码里面要控制物品个数。01背包其实可以看出是多重背包的一个特例;
01背包,完全背包,多重背包对比总结
这三种背包问题是比较基础的背包问题,之后有时间我可能会把背包系列补全。ps,平常面试基本的背包问题掌握这三种够用了。其他竞赛级别的背包有兴趣可以了解。下面仅以一维dp,即最终优化版对比;二维的不会有顺序问题;
组合问题还是排列问题
- 组合问题:01背包和完全背包,都是组合问题的时候,遍历顺序都是先物品再重量;
- 排列问题:01背包和完全背包,为组合问题的时候,即,先选入哪个物品,再选入哪个是有顺序的,遍历顺序为先重量再物品;
重量的遍历顺序
01背包为了避免重复放置的问题,重量遍历时候会从大到小;完全背包物品是无限个,循环重量的时候为从小到大;
关于递推公式
我们的背包问题递推公式都是取max,其他也有可能是取最小值,个数。。。具体题目,多去lc上刷一些就能体会到。