/***
* 问题:分割等和子集
* 解决方法:动态规划、递归法:
* 1、建立状态
* 2、状态转移方程
* 第一步、先求出和,判断其是否可以被2整除
* 第二步、for循环的确定dp
* 递归法:时间会超时,函数的调度太大
* 动态规划:相当于背包的问题
* 在数组中找到一些数值去填充target
* 从而可以确定状态boolean dp[i]表示target为i时用数组中的元素是否可以被填满
* 进一步的确定状态转移方程dp[j]=dp[j-i];表示如果dp[j-i]可以被填满则dp[j]也可以被填满
* java:
* class Solution {
private int target=0;
public boolean canPartition(int[] nums) {
for(int i=0;i<nums.length;++i)
target+=nums[i];
if(target%2!=0)return false;
target=target>>1;
return dfs(nums,0,target);
}
public boolean dfs(int[] nums,int index,int target)
{
if(target==0)return true;
else if(target<0)return false;
for(int i=index;i<nums.length;++i)
if(dfs(nums,i+1,target-nums[index]))return true;
return false;
}
}
* c++:
* class Solution {
private:
int sum=0;
int target=0;
public:
bool dfs(vector<int>& nums,int index,int target)
{
if(target==0)return true;
else if(target<0)return false;
for(int i=index;i<nums.size();++i)
if(dfs(nums,i+1,target-nums[index]))return true;
return false;
}
public:
bool canPartition(vector<int>& nums) {
for(int i=0;i<nums.size();++i)
sum+=nums[i];
if(sum%2!=0)return false;
target=sum>>1;
return dfs(nums,0,target);
}
};
*动态规划:
* class Solution {
private:
int target=0;
vector<bool>dp;
public:
bool canPartition(vector<int>& nums) {
for(int i=0;i<nums.size();++i)
target+=nums[i];
if(target%2!=0)return false;
target=target>>1;
dp=vector<bool>(target+1,false);
for(int i=0;i<nums.size();++i)
for(int j=target;j>=nums[i];--j)
{
if(j==nums[i])dp[j]=true;
else if(dp[j]==false)
dp[j]=dp[j-nums[i]];
}
return dp[target];
}
};
*/
![]()