416. 分割等和子集 - 01背包中判断是否装满的问题

✅01背包中是"否能装满"的问题

如果能把数组分割成两个子集且使得子集的元素和相等,那么证明该集合的元素总和必须要是能被2整除的,这是一个前提条件

假设总和为sum,那问题就转化成了余下的元素是否能装满容量为sum / 2的背包

再其次,因为每一个元素只能使用一次,所以这是一个0 - 1背包

💡这里设dp[i]的含义是容量为i的背包所能装的最大价值(这里的价值其实就是重量)。判断条件是:只需要满足dp[sum / 2] = sum /2,即可说明能够装满sum / 2的背包

dp数组的含义

  • dp[j]是指容量为j的背包所能装的最大价值(这里的价值其实就是重量)。

递推公式

  • 直接经典0 - 1背包递推公式 : dp[j] = max(dp[j], dp[j - num[i]] + num[i])

初始化

  • 这里只需要全部初始化为0就好了

遍历顺序

  • 因为这里使用的是一维的滚动数组!所以第一层的for是遍历物品,是正序,而第二层的for是遍历容量,因为这里每一个物品只能放入一次,所以容量是倒序的!如果容量是正序的,那么说明一个物品可以被放入多次!
class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
        }
        //若总和不为偶数,则无法满足条件
        if (sum % 2 != 0)return false;
        else {
            sum = sum / 2;
            vector<int> dp(10010, 0);
            for (int i = 0; i < nums.size(); i++) {
                for (int j = sum; j >= nums[i]; j--) {
                    dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
                }
            }
            //如果dp[i] = i,则是能够装满!!!
            return dp[sum] == sum ? true : false;
        }
    }
};
posted @   北原春希  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示