思路: 动态规划算法解决背包问题(动态规划与分治算法区别:动态规划的下一步再前一步作出改动的基础上进行,分治算法下一步跟前一步没啥关系)。
1、判断背包最大容量能否放下
2、物品重量小于背包最大容量,将 背包目前价值 和 背包腾出该物品空间后剩余价值+该物品价值做对比,哪个价值高放哪个放入
例子:背包内最大容量为5,即将放入一个电脑(价值5000,容量4),背包内原来有一瓶水(价值2000,容量1)一个相机(价值6000,容量3)。
原来的背包(2000+6000=8000)> 电脑(5000)+ 水(2000)。所以不将电脑放入背包
/**
* @author 王木风
* @create 2020-08-23 14:34
*/
public class KnapsackProblem {
public static void main(String[] args) {
int[] w = {1, 4, 3};//物品重量
int[] val = {1500, 3000, 2000};//物品价值
int m = 4;//背包容量
int n = val.length;
//前i个物品中能装入容量为j的背包的最大价值
int[][] v = new int[n + 1][m + 1];
//记录商品放入情况
int[][] path = new int[n + 1][m + 1];
for (int i = 1; i < v.length; i++) {//不处理第一行
for (int j = 1; j < v[0].length; j++) {//不处理第一列
if (w[i - 1] > j) {//因为i从1开始,导致w数组也从1开始,需要-1
v[i][j] = v[i - 1][j];
} else {
//v[i][j] = Math.max(v[i - 1][j], val[i - 1] + v[i - 1][j - w[i - 1]]);
//为了记录路径,不能简单使用上面式子
if (v[i - 1][j] < val[i - 1] + v[i - 1][j - w[i - 1]]) {
v[i][j] = val[i - 1] + v[i - 1][j - w[i - 1]];
path[i][j] = 1;
} else {
v[i][j] = v[i - 1][j];
}
}
}
}
for (int i = 0; i < v.length; i++) {
for (int j = 0; j < v[i].length; j++) {
System.out.print(v[i][j]+" ");
}
System.out.println();
}
//输出放入了那些商品
System.out.println("============");
for (int i = 0; i < path.length; i++) {
for (int j = 0; j < path[i].length; j++) {
if (path[i][j] == 1) {
System.out.println("第"+i+"个商品放入背包");
}
}
}
}
}