代码实现
/** * 动态规划解决01背包问题 */ public class Bag { public static void main(String[] args) { // 重量和价值 int[] w = {1, 4, 3}; int[] val = {1500, 3000, 2000}; // 背包容量 int m = 4; // 物品个数 int n = val.length; // 定义一个二维数组,记录存放情况 int[][] path = new int[n + 1][m + 1]; // 创建二维数组,表示表 int[][] v = new int[n + 1][m + 1]; // 初始化第一行、第一列 for (int i = 0; i < v.length; i++) { v[i][0] = 0; } for (int i = 0; i < v[0].length; i++) { v[0][i] = 0; } // 动态规划处理(不处理没物品行和0重量列) for (int i = 1; i < v.length; ++i) { for (int j = 1; j < v[0].length; ++j) { // 物品超出背包容量 if (w[i - 1] > j) { // 从上一个格子拿方案 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-else替代 // 拿到上次的最优 int lastBest = v[i - 1][j]; // 拿到这次最优 int thisTimeBest = (val[i - 1] + v[i - 1][j - w[i - 1]]); if (lastBest < thisTimeBest) { // 把当前情况记录下来 v[i][j] = thisTimeBest; path[i][j] = 1; } else { v[i][j] = lastBest; } } } } // 遍历结果 for (int[] ints : v) { for (int i : ints) { System.out.print(i + "\t"); } System.out.println(); } System.out.println("方案如下:"); // 输出最终放入的商品 int i = path.length - 1; int j = path[0].length - 1; // 逆向遍历 while (i > 0 && j > 0) { if (path[i][j] == 1) { System.out.printf("第%d个商品放入背包\n", i); // 遍历拥有最佳策略的商品 // 并按照剩余磅数进行遍历 j -= w[i - 1]; } // 上移 --i; } } }