0
点赞
收藏
分享

微信扫一扫

动态规划02---你的背包怎么背也背不烂~~~专治各种01背包问题

晚安大世界 2022-03-11 阅读 65

01背包的理论基础可以参考一下这个,真心觉得不错错

看完上边这个之后,应该对背包问题有了一个初步的了解了,那接下来趁热打铁,看看下边这个

01背包的简化,之后的题主要靠这个

==============================================================================

第一题:力扣416题

解题思路:

可以把数组之和的一半作为背包所能承受的最大重量,把数组中的每个数当作是要往书包中投放的物品,然后就先遍历每个物品,紧接着倒叙遍历背包。主要的还是递推公式:无非就是两种情况,第一种,该物品的重量大于此时背包所能承受的重量,不放它的收益;另一种就是放上这个物品,看看此时收益,二者取最大的即可。

代码如下:

class Solution {
    public boolean canPartition(int[] nums) {
        //先求和,用来作为分子集的标准
        int sum = 0;
        for(int num : nums) {
            sum += num;
        }
        //求完和之后判断一下,能不能劈两半
        if(sum % 2 == 1) {
            return false;
        }
        //开始转换成 01背包问题 了
        int target = sum / 2;
        //因为还得放0
        int[] dp = new int[target+1];
        //先遍历物品,在遍历背包,并且背包得反向遍历
        for(int i = 0; i < nums.length; i++) {
            for(int j = target; j >= nums[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
            }
        }
        return target == dp[target];
    }
}

类似题目:力扣1049题

直接放代码:

class Solution {
    public int lastStoneWeightII(int[] stones) {
        int sum = 0;
        for(int stone : stones) {
            sum += stone;
        }
        int target = sum / 2;
        int[] dp = new int[target+1];
        for(int i = 0; i < stones.length; i++) {
            for(int j = target; j >= stones[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j-stones[i]] + stones[i]);
            }
        }
        return sum - 2 * dp[target];
    }
}

就是最后的处理方式不同

==============================================================================

第二题:力扣494题

代码如下:

class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        if ((target + sum) % 2 != 0) {
            return 0;
        }
        if(Math.abs(target) > sum) {
            return 0;
        }
        int size = (target + sum) / 2;
        int[] dp = new int[size + 1];
        dp[0] = 1;
        for (int i = 0; i < nums.length; i++) {
            for (int j = size; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[size];
    }
}

可以做下这个题:力扣474题

举报

相关推荐

0 条评论