背景
有三个物品,,它们的信息如下:
物品 | 物品1 | 物品2 | 物品3 |
---|---|---|---|
体积 | 1 | 2 | 4 |
价值 | 6 | 10 | 12 |
现在有一个能够容量为5的背包,将上述三个物品任意放入背包中,要求放入背包的物品的总价值最大;
思路
将背包容量按照单位容量划分,依次计算放入物品时被背包中物品的总价值:
背包容量 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
物品1 | 6 | 6 | 6 | 6 | 6 |
物品2 | 6 | 10 | 16 | 16 | 16 |
物品3 | 6 | 10 | 16 | 16 | 18 |
放物品1
不论背包容量为多少时,物品1都可以放下,所以容量1~5在放入物品的最大在总价值为6
放物品2
- 背包容量为1时,物品2放不进去,所以此时背包中的最大总价值是放入物品1时对应容量的最大总价
- 背包容量为2时,物品2可以放进去,放入物品2是的最大总价值为10,比不放入物品2时的最大总价值6要大
- 背包容量为3时,放入物品2时的最大总价值为:物品2的价值和放入前一个物品时在容量为1(放入物品2的剩余容量)之和,为16,比不放入物品2时的最大总价值6要大
- 背包容量为4时,放入物品2时的最大总价值为:物品2的价值和放入前一个物品时在容量为2(放入物品2的剩余容量)之和,为16,比不放入物品2时的最大总价值6要大
- 背包容量为5时,放入物品2时的最大总价值为:物品2的价值和放入前一个物品时在容量为3(放入物品2的剩余容量)之和,为16,比不放入物品2时的最大总价值6要大
放物品3
- 背包为1、2、3时,物品3都放不进去,所以各容量下的最大总价值和放入物品2时的对应的最大总价值相同
- 背包容量为4时,物品3可以放入。放入物品3的总价值就时物品3的价值12(无法再放入其他物品),小于放入物品2时容量为4时的最大总价值16
- 背包容量为5时,放入物品3的总价值为:物品3的价值 + 放入物品2背包容量为1(装入物品3后的剩余容量)之和 = 12 + 6,为18,大于放入物品2时背包容量为5时的背包最大总价值16
代码实现
public static void main(String[] args) {
int[] values = {60, 100, 120};
int[] volumes = {1, 2, 4};
int backPackTotalCapacity = 5; //背包总容量
int n = 3; //物品个数
int[][] maxValue = new int[n + 1][backPackTotalCapacity + 1];
Arrays.fill(maxValue[0], 0);
for (int i = 1; i <= volumes.length; i++) { // 每次加的物品
maxValue[i][0] = 0; // 容量为0时,对应总价值也为0
for (int capacity = 1; capacity <= backPackTotalCapacity; capacity++) { //分割的背包容量
if (volumes[i - 1] <= capacity) { //表示当前背包容量下这个背包可以装进去
maxValue[i][capacity] = Math.max(values[i - 1] + maxValue[i - 1][capacity - volumes[i-1]], maxValue[i - 1][capacity]);
} else {
maxValue[i][capacity] = maxValue[i - 1][capacity];
}
}
}
System.out.println("装的物品的总价值为:" + maxValue[n][backPackTotalCapacity]);
}