零一背包与完全背包

零一背包

给定一组物品,每个物品有自己的重量和价值,以及一个背包的容量。目标是选择一些物品放入背包中,使得在不超过背包容量的情况下,背包中物品的总价值最大化。

思路

1、定义问题dp[i][j]:表示前i个物品中当容量为j时的最大价值

2、定义状态转移方程

(1) Dp[i][j] = math.max(dp[i][j-1], values[i] + dp[i - 1][j - weights[i]])

(2) 表示:如果放则为values[i] + dp[i - 1][j - weights[i]],如果不放则为之前计算好且容量为j-1时的最优解

3、定义初始值:dp[i][j]初始化为0,表示不放入物品时,背包的最大价值为0

 

代码

 

public class ZeroOneKnapsack {

    public static int knapsack(int[] weights, int[] values, int capacity) {
        int n = weights.length;
        int[][] dp = new int[n+1][capacity+1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= capacity; j++) {
                if (weights[i-1] <= j) {
                    dp[i][j] = Math.max(values[i-1] + dp[i-1][j-weights[i-1]], dp[i-1][j]);
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        return dp[n][capacity];

    }

    public static void main(String[] args) {
        int[] weights = {2, 3, 4, 5};
        int[] values = {3, 4, 5, 6};
        int capacity = 8;
        int maxTotalValue = knapsack(weights, values, capacity);
        System.out.println("Maximum total value: " + maxTotalValue);
    }
}

 

完全背包

在完全背包问题中,同样有一个背包容量为C,以及一组物品,每个物品有自己的重量和价值。不同的是,每个物品可以选择无限次放入背包中。目标是选择物品放入背包中,使得在不超过背包容量的情况下,背包中物品的总价值最大化。

思路

1、定义问题dp[j]:表示容量为j时可放入的最大价值

2、定义状态转移方程:

(1) Dp[j] = max(dp[j], values[i] + dp[j - weights[i]])

(2) 表示如果不放则为之前定义好且容量为j时的最优解,如果放则为values[i] + dp[j - weights[i]]

3、定义初始值:

代码

public class UnboundedKnapsack {

    public static int knapsack(int[] weights, int[] values, int capacity) {
        int n = weights.length;
        int[] dp = new int[capacity+1];

        for (int i = 0; i <= capacity; i++) {
            for (int j = 0; j < n; j++) {
                if (weights[j] <= i) {
                    dp[i] = Math.max(dp[i], values[j] + dp[i-weights[j]]);
                }
            }
        }
        return dp[capacity];
    }


    public static void main(String[] args) {
        int[] weights = {2, 3, 4, 5};
        int[] values = {3, 4, 5, 6};
        int capacity = 8;
        int maxTotalValue = knapsack(weights, values, capacity);
        System.out.println("Maximum total value: " + maxTotalValue);
    }

}

总结

零一背包与完全背包的max区别在于不放时的场景

(1) 零一背包:dp[i-1][j]表示不放那就最大值依赖于前i-1个物品的最大值

(2) 完全背包:dp[i]表示不放那就依赖于之前已经计算好的容量为i时的最优解

posted @ 2023-08-06 18:01  Adom_ye  阅读(13)  评论(0编辑  收藏  举报