分割等和子序列

416. 分割等和子集

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

思路:

可以认为是对数组中取部分元素,使得加合是所有元素之和的一半(转换成这个问题就会发现本题是标准的01背包问题,就是看每个元素是取还是不取就行)。

则dp[i][j]表示前i个元素,结果是j是否可能存在。dp[i][j]的构成是:

dp[i-1][j],视为第i个元素不取。

dp[i-1][j-num[i]],取第i个元素,但前提是dp[i-1][j-num[i]]得下标合法且存在。

dp[i][j]=dp[i-1][j](一定有) ||dp[i-1][j-num[i]](可能有)。

初始化:

对于i=0时,仅当j=0为真,其余情况均不可能达到。

对于j=0时,对任意i为真,因为一个都不取一定满足总和是j。

class Solution {
public:
    bool canPartition(vector<int>& nums) {
    int n=nums.size();
    int k=0;
    nums.insert(nums.begin(),0);
    for(auto e:nums)
    {
        k+=e;
    }
    if(k%2!=0)
    return false;
    k/=2;
    vector<vector<bool>>dp(n+1,vector<bool>(k+1,false));

    for(int i=0;i<=n;i++)
    {
        dp[i][0]=true;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
           dp[i][j]=dp[i-1][j];
           if(j>=nums[i]&&dp[i-1][j-nums[i]])
           dp[i][j]=dp[i-1][j]||dp[i-1][j-nums[i]];
        }
    }

    return dp[n][k];


    }
};

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值