###### 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; } ```