0-1背包动态规划解法

134 阅读2分钟

0-1背包问题

动态规划解法

0-1背包问题描述:
给定一个可装质量为target的背包,给定n个重量为weights[i]的物品(i可取0,n-1),这n个物品对应的价值为values[i](i可取0,n-1),问怎样装可以使背包中的物品价值最大。

  • 动态规划解法:
  • 首先需要考虑动态规划的五个步骤:
  • (1)确定dp数组,dp[i][j]表示容量为j的背包,可选物品为0-i,可装的最大价值
  • (2)初始化dp[][]数组,dp[i][0]均为0,dp[0][j]根据背包的容量大小,当背包容量小于第一个物品的重量时,dp[0][j]为0;当背包容量大于等于第一个物品的重量时,dp[0][j]为value[0]。
  • (3)确定递推公式:当可选物品为0-i、背包容量为j时,即dp[i][j],从上一个状态可以推出,分为两种情况: 1、第i个物品的质量大于背包容量,那么第i个物品不能装入背包中;
    2、第i个物品的质量小于背包容量,那么第i个物品可以装入背包中,那么又分为两种情况:
    第i个物品装入背包:dp[i][j] = dp[i-1][j];
    第i个物品不装入背包:dp[i][j] = dp[i-1][j - weights[i]] + values[i];
  • (4)确定遍历顺序:先遍历物品,再遍历背包容量。这样的思路比较容易理解。
  • (5)手动模拟dp[][]数组。
代码实现
public class bagProblem {
    public static void main(String[] args) {
        int weights[] = {1,3,4};
        int values[] = {15,20,30};
        int target = 4;
        bagSolution(weights,values,target);
    }

    public static void bagSolution(int weights[],int values[],int target){
        // 定义dp数组
        int[][] dp = new int[weights.length][target+1];
        // 初始化dp数组
        for (int j = weights[0]; j <= target ; j++) {
            dp[0][j] = values[0];
        }

        for (int i = 1; i < weights.length; i++) {
            for (int j = 0; j <= target ; j++) {
                if (j < weights[i]){
                    dp[i][j] = dp[i-1][j];
                }else {
                    dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-weights[i]] + values[i]);
                }
            }
        }

        for (int i = 0; i < weights.length; i++) {
            for (int j = 0; j <= target; j++) {
                System.out.print(dp[i][j] + "\t");
            }
            System.out.println("\n");
        }
    }
}
dp数组打印

image.png