zoukankan      html  css  js  c++  java
  • 416. 分割等和子集(0-1背包)

     

    难度中等

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

    示例 1:

    输入:nums = [1,5,11,5]
    输出:true
    解释:数组可以分割成 [1, 5, 5] 和 [11] 。

    示例 2:

    输入:nums = [1,2,3,5]
    输出:false
    解释:数组不能分割成两个元素和相等的子集。



    首先回忆一下背包问题大致的描述是什么:

    给你一个可装载重量为 W 的背包和 N 个物品,每个物品有重量和价值两个属性。其中第 i 个物品的重量为 wt[i],价值为 val[i],现在让你用这个背包装物品,最多能装的价值是多少?

    那么对于这个问题,我们可以先对集合求和,得出 sum,把问题转化为背包问题:

    给一个可装载重量为 sum / 2 的背包和 N 个物品,每个物品的重量为 nums[i]。现在让你装物品,是否存在一种装法,能够恰好将背包装满?

    
    
    class Solution {
    public:
        bool canPartition(vector<int>& nums) {
        int sum = 0, n = nums.size();
        for (int num : nums) sum += num;
        if (sum % 2 != 0) return false;
        sum = sum / 2;
        vector<int> dp(sum + 1, 0);
        for (int i = 1; i <=n; i++) 
            for (int j = sum; j >= 0; j--) 
                if (j - nums[i-1] >= 0) 
                    dp[j] = max(dp[j],dp[j - nums[i-1]]);
    
        return dp[sum]==sum;
    }
    };




    class Solution {
    public:
        bool canPartition(vector<int>& nums) {
            int sum = 0;
            int max_num =0;
            for(auto i : nums) {
                sum+=i;
                max_num = max(max_num,i);
            }
            if(sum%2==1) return false;
            
            if (max_num>sum/2) return false;//[1,2,5]
            sum = sum/2;
            int n = nums.size();
            vector<vector<bool>> dp = vector<vector<bool>>(n+1,vector<bool>(sum+1,false));
            //前i个背包,正好装满j的容量
            //dp[0][..] = true
            //dp[..][0] = false
            for(int j = 0;j < sum+1;j++) {
                dp[0][j] = true;
            }
            for(int i = 1; i < n+1;i++) {
                for(int j = 1; j < sum+1;j++) {
                    if (j>nums[i-1]) {
                        dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i-1]];
                    } else {
                        dp[i][j] = dp[i-1][j];
                    }
                }
            }
            return dp[n][sum];
        }
    };
  • 相关阅读:
    TranslateAnimation 运行动画后实际位置不正确问题
    Linux下如何编译并运行C程序
    row_number() OVER (PARTITION BY COL1 ORDER BY COL2)
    C++软件开发常用辅助软件——gprof
    C++软件开发常用辅助软件——Cppcheck
    C++软件开发常用辅助软件——SCons
    C++软件开发常用辅助软件——Valgrind
    救援linux
    C/C++代码覆盖率生成
    排列的逆
  • 原文地址:https://www.cnblogs.com/zle1992/p/15400246.html
Copyright © 2011-2022 走看看