Create 494. Target Sum.md

This commit is contained in:
ShusenTang 2019-11-26 21:26:54 +08:00 committed by GitHub
parent f42f9915af
commit 0e475200c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,36 @@
# [494. Target Sum](https://leetcode.com/problems/target-sum/)
# 思路
这道题给了我们一个数组元素非负和一个目标值要求给数组中每个数字前添加正号或负号所组成的表达式结果与目标值S相等求有多少种情况。
假设所有元素和为sum所有添加正号的元素的和为A所有添加负号的元素和为B则有`sum = A + B` 且 `S = A - B`,解方程得`A = (sum + S)/2`。
即题目转换成:从数组中选取一些元素使和恰好为`(sum + S) / 2`。可见这是一个恰好装满的01背包问题要求所有方案数。
我在我的博客文章[动态规划之背包问题系列](https://tangshusen.me/2019/11/24/knapsack-problem/)对常见的几类背包问题做了个总结此题的分析见5.3节,这里只给出代码。
# C++
``` C++
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int sum = 0;
// for(int &num: nums) sum += num;
sum = accumulate(nums.begin(), nums.end(), 0);
if(S > sum || sum < -S) return 0;
if((S + sum) & 1) return 0;
int target = (S + sum) >> 1;
vector<int>dp(target + 1, 0);
dp[0] = 1;
for(int i = 1; i <= nums.size(); i++)
for(int j = target; j >= nums[i-1]; j--){
dp[j] = dp[j] + dp[j - nums[i-1]];
}
return dp[target];
}
};
```