java动态规划实现01背包问题

java动态规划实现01背包问题

代码实现

/**
 * 动态规划解决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;
        }
    }
}
posted @ 2022-04-24 23:24  CoderCatIce  阅读(213)  评论(0编辑  收藏  举报