---
# System prepended metadata

title: 377. Combination Sum IV
tags: [Leetcode, medium, python, array, c++, dynamic programming]

---

###### tags: `Leetcode` `medium` `dynamic programming` `array` `python` `c++`

# 377. Combination Sum IV

## [題目連結:] https://leetcode.com/problems/combination-sum-iv/

## 題目:
Given an array of **distinct** integers ```nums``` and a target integer ```target```, return the number of possible combinations that add up to ```target```.

The test cases are generated so that the answer can fit in a **32-bit** integer.

**Follow up**: What if negative numbers are allowed in the given array? How does it change the problem? What limitation we need to add to the question to allow negative numbers?

**Example 1:**
```
Input: nums = [1,2,3], target = 4
Output: 7
Explanation:
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.
```
**Example 2:**
```
Input: nums = [9], target = 3
Output: 0
```

## 解題想法:
* Combination Sum系列題目:
	* [39. Combination Sum](/W7B2e-02R7GECNxeVr0_vA)
	* [40. Combination Sum II](/YxlQmfbsRV2-hX7xVVdtiw)
	* [216. Combination Sum III](/1FxuhR0-QQKswHRda053fA)
* 此題為使用數組中的數組合為target
	* 每個數字可重複使用
	* 組合數字一樣，順序不一樣: 視為不同組合

* 使用DP:
	* 定義: **dp[i]表示目標數為i的解的個數**
		* dp=[0] * (target+1)
		* init: dp[0]=1 ，組成合為0，啥都不選，一種解
	* 雙迴圈:
	* 第一圈:
		* 目標數從i=0遍歷到target
	* 第二圈:
		* 對於每個i，遍歷nums
		* 若i>= val of nums 則代表可以繼續拆分
			* dp[i]+=dp[i-val]
			* **解釋**:表示對於總和為(i-val)可以有dp[i-val]種組合後，加上val後可以組合為dp[i]
	* 可以想成爬樓梯問題:
		* 一次可以爬val階，則爬到i時的可能數

## Python:
``` python=
class Solution(object):
    def combinationSum4(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        #dp[i]表示目標數為i的解的個數
        #從i遍歷到target
        #其中對於每個i 遍歷nums : 若i>=val 則代表可繼續拆分
        dp=[0]*(target+1)
        dp[0]=1
        for i in range(1,target+1):
            #想成爬樓梯問題: 一次可以爬val階 則爬到i時的可能數
            #可以想成: target=4 所以dp[4]=dp[3]+dp[2]+dp[1]
            for val in nums:
                if i>=val:
                    dp[i]+=dp[i-val]
        return dp[target]

result=Solution()
ans=result.combinationSum4(nums = [1,2,3], target = 4)
print(ans)
```

## C++:
``` cpp=
#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<unsigned int> dp(target+1,0);
        dp[0]=1;
        for(int val=1; val<=target; val++){
            for(const int num:nums){
                if(val-num>=0)
                    dp[val]+=dp[val-num];
            }
        }
        return dp[target];
    }
};

int main(){

    Solution res;
    vector<int> nums={1,2,3};
    int target=4;
    int ans=res.combinationSum4(nums,target);
    cout<<ans<<endl;
    return 0;
}

```