Input: [1, 5, 11, 5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].
#include<iostream>
#include<vector>
using namespace std;
//dp[i]表示原数组是否可以取出若干个数字,其和为i
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
for(int i = 0 ; i < nums.size() ; i ++)
{
sum += nums[i];
}
cout << "sum=" << sum << endl;
if(sum % 2 != 0) //判断整个和是否为偶数
return 0;
int target = sum / 2;
cout << "target=" << sum/2 << endl;
vector<int> dp(target + 1, 0);
dp[i]表示原数组是否可以取出若干个数字,其和为i
dp[0] = 1; //边界
for(int i = 0 ; i < nums.size(); i ++)
{
cout << "nums[i]=" << nums[i] << endl;
for(int j = target; j >= nums[i]; j --)
{
//如果 dp[j - nums[i]] 为true的话,说明现在已经可以组成 j-nums[i] 这个数字了
//再加上nums[i],就可以组成数字j了
cout << "j=" << j << "," << "dp[j]=" << dp[j] << "," << dp[j-nums[i]] << endl;
dp[j] = dp[j] || dp[j-nums[i]];
}
cout << "--------------------------------------------" <<endl;
}
return dp[target];
}
};
int main()
{
vector<int> temp {1, 3, 2, 4};
Solution text;
cout << text.canPartition(temp) << endl;
return 0;
}
打印:
sum=10
target=5
nums[i]=1
j=5,dp[j]=0,0
j=4,dp[j]=0,0
j=3,dp[j]=0,0
j=2,dp[j]=0,0
j=1,dp[j]=0,1 //dp[1] = 1 ,数组是否可以取出若干个数字,其和为1,因为第一个数为1
--------------------------------------------
nums[i]=3
j=5,dp[j]=0,0
j=4,dp[j]=0,1 //dp[4] = 1 ,数组是否可以取出若干个数字,其和为4,因为dp[1]=1,nums[i]=3,相加和刚好是4
j=3,dp[j]=0,1 //dp[3] = 1 ,数组是否可以取出若干个数字,其和为3,刚好这个数为3
--------------------------------------------
nums[i]=2
j=5,dp[j]=0,1 //dp[5] = 1 ,数组是否可以取出若干个数字,其和为5,因为d[3]=1
j=4,dp[j]=1,0 //dp[4] = 1 ,上面已经为1了
j=3,dp[j]=1,1 //dp[3]和dp[1]都为1
j=2,dp[j]=0,1 //dp[0]为1
--------------------------------------------
nums[i]=4
j=5,dp[j]=1,1 //d[5]和dp[1]都为1
j=4,dp[j]=1,1 //d[4]和dp[0]都为1
--------------------------------------------
1
上面的思路相对数组中每个数求dp,最后就会找到dp[target]是否为true,如果 dp[j - nums[i]] 为true的话,说明现在已经可以组成 j-nums[i] 这个数字了,再加上nums[i],就可以组成数字j了。当j=target是同样道理,要想找到dp[target]为true,就找找到数组中几个值的和为target时,对应下标的dp值为true,这样反推dp[target]为true。
参考地址:https://blog.youkuaiyun.com/qq_40320556/article/details/89875463