# LC 494. Target Sum
### [Problem link](https://leetcode.com/problems/target-sum/)
###### tags: `leedcode` `python` `c++` `medium` `DP`
You are given an integer array <code>nums</code> and an integer <code>target</code>.
You want to build an **expression** out of nums by adding one of the symbols <code>'+'</code> and <code>'-'</code> before each integer in nums and then concatenate all the integers.
- For example, if <code>nums = [2, 1]</code>, you can add a <code>'+'</code> before <code>2</code> and a <code>'-'</code> before <code>1</code> and concatenate them to build the expression <code>"+2-1"</code>.
Return the number of different **expressions** that you can build, which evaluates to <code>target</code>.
**Example 1:**
```
Input: nums = [1,1,1,1,1], target = 3
Output: 5
Explanation: There are 5 ways to assign symbols to make the sum of nums be target 3.
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3
```
**Example 2:**
```
Input: nums = [1], target = 1
Output: 1
```
**Constraints:**
- <code>1 <= nums.length <= 20</code>
- <code>0 <= nums[i] <= 1000</code>
- <code>0 <= sum(nums[i]) <= 1000</code>
- <code>-1000 <= target <= 1000</code>
## Solution 1 - DP
#### Python
```python=
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
if abs(target) > sum(nums) or (sum(nums) + target) % 2:
return 0
bagSize = (sum(nums) + target) // 2
dp = [0] * (bagSize + 1)
dp[0] = 1
for i in range(len(nums)):
for j in range(bagSize, nums[i] - 1, -1):
dp[j] += dp[j - nums[i]]
return dp[-1]
```
#### C++
```cpp=
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int target) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if ((target + sum) % 2) {
return 0;
}
/*
* let bagSize = subSum of nums, then, sum of nums can split to bagSize and sum - bagSize.
* => target = bagSize - (sum - bagSize)
* => bagSize = (target + sum) / 2
*/
int bagSize = (target + sum) / 2;
if (bagSize < 0) {
return 0;
}
vector<int> dp(bagSize + 1, 0);
dp[0] = 1;
for (int i = 0; i < nums.size(); i++) {
for (int j = bagSize; j >= nums[i]; j--) {
dp[j] += dp[j - nums[i]];
}
}
return dp.back();
}
};
```
>### Complexity
>m = bagSize
>n = nums.length
>| | Time Complexity | Space Complexity |
>| ----------- | --------------- | ---------------- |
>| Solution 1 | O(mn) | O(m) |
## Note
sol1:
1.
```cpp=
if ((target + sum) % 2) {
return 0;
}
```
如果target 與 sum 相差1, 則永遠不可能達成題目要求.
2.
與一般01背包不同, 這次是求裝滿背包有幾種方法而不是背包最多能裝多重.
dp公式變為
```cpp=
dp[j] += dp[j - nums[i]];
```
[ref](https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0494.%E7%9B%AE%E6%A0%87%E5%92%8C.md)