一:论语
二:题目
三:上码
class Solution {
public:
/**
思路:1.分析题意:这是将原集合分成一个正子集和一个负子集;
例如题目中给出的[1,1,1,1,1], target = 3;
那么我们就可以得出: 加法和就是4,减法和就是1 = 5-4;
target: 4-(5-4) = 3;
left = (5+3)/2 = 4;
left - right = target;
right = (sum - left)
left - (sum-left) = target;
left = (sum+target)/2;
2.思路:
1>:确定dp数组和下标的含义
dp[j] 表示背包容量为j的背包 最多有dp[j]种方法
2>:确定dp数组的递推公式
dp[j] += dp[j-nums[i]]
3>:确定dp数组的初始化
首个元素初始话为1其余元素初始化为0
4>:确定dp数组的遍历顺序
外层背包、内层背包的重量(逆序)
5>:举例验证:
*/
int findTargetSumWays(vector<int>& nums, int target) {
int sum = accumulate(nums.begin(),nums.end(),0);
if((sum+target)%2 == 1) return 0;//这个就是说明正子集是不存在的
if(abs(target) > sum) return 0;
int bigSize = (sum+target)/2;
vector<int> dp(bigSize+1,0);
dp[0] = 1;//也就是不装入也是1
for(int i = 0; i < nums.size(); i++) {
for(int j = bigSize; j >= nums[i]; j--) {
dp[j] += dp[j-nums[i]];
}
}
return dp[bigSize];
}
};
一丢丢