一、题目

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



示例 1:

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

示例 2:

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



提示:

1 <= nums.length <= 200
1 <= nums[i] <= 100


二、思路
  • 问是否可以划分为2部分,若和sum为奇数必然为false。若sum的一半比最大值还小,那么也是false
  • 接下来用01背包判断是否能够选出价值为sum/2的物品,若能选出代表可以划分为相同的2部分
三、代码

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

return dp[sum] == sum;
}
};