优化0-1揹包问题

public static int max_back() {        // 0-1 揹包优化,使用一维数组来实现
        int[] weight = new int[]{2, 2, 6, 5, 4};
        int[] value = new int[]{6, 3, 5, 4, 6};

        int Max = 10;   // 最大容量
        int n = 5;      // 物品件数

        int[] dp = new int[Max+1];
        dp[0] = 0;
        for(int i = 0; i < n; i++) {
            for(int j = Max; j >= weight[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j-weight[i]] + value[i]);
            }
        }
        return dp[Max];
    }

 

leetcode:416 分割等和子集   https://leetcode-cn.com/problems/partition-equal-subset-sum/

给定一个只包含正整数非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

前期思路:求出数组中所有整数之和sum,判断是否能分成两个子集,转化为判断是否存在部分数组元素之和等于sum/2

public boolean canPartition(int[] nums) {
        int len = nums.length;
        if(len <= 1) return false;
        int sum = 0;
        for(int i = 0; i < len; i++) sum += nums[i];
        if(sum%2 == 1) return false;

        sum /= 2;

        int[] dp = new int[sum+1];
        // 转化为 0-1 揹包问题,sum此时就代表揹包的容量
        // 即判断 是否容量为sum时,能够达到sum!!!!
        dp[0] = 0;
        for(int i = 0; i < len; i++) {
            for(int j = sum; j >= nums[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]);
            }
        }

        return dp[sum] == sum;
    }

 

将判断数组中是否存在一部分整数之和等于sum/2,转化为0-1揹包问题。

一部分整数之和,对应的就是对于一个整数,我们可以选择放到揹包中和不放到揹包中。

最后,只需要判断,当揹包容量为sum/2时,揹包中的最大价值(重量?, 这里应该都是一样的) 是否可以达到sum/2

点赞