LCR 101. 分割等和子集
给定一个非空的正整数数组 nums ,请判断能否将这些数字分成元素和相等的两部分。
示例 1:
输入:nums = [1,5,11,5]
输出:true
解释:nums 可以分割成 [1, 5, 5] 和 [11] 。
示例 2:
输入:nums = [1,2,3,5]
输出:false
解释:nums 不可以分为和相等的两部分
提示:
1 <= nums.length <= 200
1 <= nums[i] <= 100
动态规划01背包
dp[i][j]表示从前 i 个数字中选出若干个,刚好可以使得被选出的数字其和为 j。
本题就是要返回dp[n-1][target]
class Solution {
public:bool dp[205][10005];bool canPartition(vector<int>& nums){dp[0][0]=1;int n=nums.size();int sum=0;for(int i=0;i<n;i++) sum+=nums[i];if(sum%2!=0) return 0;int target=sum/2;for(int i=1;i<=target;i++) dp[0][i]=0;for(int i=1;i<n;i++){for(int j=0;j<=target;j++){if(nums[i]>j) dp[i][j]=dp[i-1][j];else dp[i][j]=dp[i-1][j]|dp[i-1][j-nums[i]];}}return dp[n-1][target];}
};
优化
class Solution {
public:bool dp[10005];bool canPartition(vector<int>& nums){dp[0]=1;int n=nums.size();int sum=0;for(int i=0;i<n;i++) sum+=nums[i];if(sum%2!=0) return false;int target=sum/2;for(int i=1;i<n;i++){for(int j=target;j>=nums[i];j--){if(dp[target]) return true;dp[j]=dp[j]|dp[j-nums[i]];}}return dp[target];}
};