/*** * 问题:分割等和子集 * 解决方法:动态规划、递归法: * 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]; } }; */