代码随想录算法训练营第四十二天|01背包问题 二维、01背包问题 一维、416. 分割等和子集

目录

 01背包问题 二维 

01背包问题 一维

416. 分割等和子集 


正式开始背包问题,背包问题还是挺难的,虽然大家可能看了很多背包问题模板代码,感觉挺简单,但基本理解的都不够深入。 如果是直接从来没听过背包问题,可以先看文字讲解慢慢了解 这是干什么的。如果做过背包类问题,可以先看视频,很多内容,是自己平时没有考虑到位的。 背包问题,力扣上没有原题,大家先了解理论,今天就安排一道具体题目。

 01背包问题 二维 

代码随想录

01背包问题 一维

代码随想录

一维的理解需要在理解二维的基础上进行优化的,其实只要关注背包容量j下所取商品使得背包取最大价值,这就是一维的原理,具体的还有很多小细节,比如只能从后往前遍历,对听卡哥视频的说明就好,理解万岁


416. 分割等和子集 

本题是 01背包的应用类题目

代码随想录

视频讲解:动态规划之背包问题,这个包能装满吗?| LeetCode:416.分割等和子集_哔哩哔哩_bilibili

题解思路:

先听卡哥对背包问题的理论阐述,本题就是很典型的01背包问题,我是用二维空间去写的,动态规划最重要的一步就是确定dp[i][j]含义:添加第i个物品,背包容量为j是的最大价值,这题的简化模型就是01问题:
1、物品的数量就是数组的大小,注意这里是从取第一件一直到取第i件遍历的(取第0件用来初始化的),每件物品的价值就是数组中的元素值大小;每件物品的重量也是数组中元素值的大小
2、因为这里是判断是否可以将数组分成元素和相等的两个子数组,**因此遍历背包的容量就是给定数组元素和一半大小。**以[3,3,3,4,5]为例说明,这群数字和为18,如果我用9去装这些数字,最大正好能装到9,是不是意味着,能把这群数字分成两堆,因此背包容量应该遍历到9才对
3、在初始化dp数组的时候,默认初始化dp[0][j] = 0,因为添加第0件商品时的价值都是0;默认初始化dp[i][0] = 0,因为背包容量为0的时候,添加任何一件物品其最大价值都为0

class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for(int i = 0; i < nums.length; i++){
            sum += nums[i];
        }

        if(sum % 2 != 0) return false;

        int[][] dp = new int[nums.length + 1][sum/2 + 1];//默认dp数组初始化值都为0
        //以[3,3,3,4,5]为例说明,这群数字和为18,如果我用9去装这些数字,最大正好能装到9,是不是意味着,能把这群数字分成两堆,因此背包容量应该遍历到9才对
        for(int i = 1; i < dp.length; i++){
            for(int j = 1; j < dp[0].length; j++){
                if(j >= nums[i-1]){
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i-1][j-nums[i-1]]+nums[i-1]);
                }else {
                    dp[i][j] = dp[i-1][j];
                }
                if(dp[i][j] == sum/2) return true;
            }
        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/tore007/article/details/131033866