代码随想录——动态规划13.分割等和子集

image

思路

难点

我只想到了:“找一个子集,每个数取或不取求其和,看是否和另一个子集的和相等 ”
但是实际上既然是两个子集相等,那么只要和等于 sum/2 即可了!
取或不取用01背包,但是不知道怎么用。

只有确定了如下四点,才能把01背包问题套到本题上来。

  1. 背包的体积为sum / 2
  2. 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  3. 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  4. 背包中每一个元素是不可重复放入。

套用01背包时,要确定容量和价值分别取什么。

代码

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        // 找一个子集,每个数取或不取求其和,看是否和另一个子集的和相等 —————— 错!!既然是两个子集相等,那么只要和等于 sum/2 即可了!
        // 取或不取——想到01背包。背包的容量取 sum/2 即可。num[i]即为重量也为价值。
        int n = nums.size();
        int sum = 0;
        for(auto x : nums)sum+=x;
        if(sum % 2 !=0 )return false;

        vector<int> dp(sum/2+1,0); // dp[j]表示容量为j的背包,能装入的最大价值
        // 当dp[sum/2]==sum/2时说明背包装满了,即找到了一个子集
        for(int i=0;i<n;i++){
            for(int j=sum/2;j>=nums[i];j--){
                dp[j] = max(dp[j],dp[j-nums[i]] + nums[i]);
            }
        }
        if(dp[sum/2] == sum/2)return true;
        else return false;
    }
};
posted @   NeroMegumi  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示