Skip to content

Latest commit

 

History

History
44 lines (37 loc) · 1.53 KB

377. Combination Sum IV.md

File metadata and controls

44 lines (37 loc) · 1.53 KB

思路

给定一个元素各不相同的数组和一个整数target,从数组从选取(可重复选)若干个数使和为target,问有多少种选法,注意一个排列就算一种选法,例如[1,2]和[2,1]是两种选法。

由于要求选法数,所以很容易想到用动态规划来求解,设

dp[i]表示target为i时的选法数(初始为0), dp[0] = 1

即dp[target]为所求。

转态转移方程也很简单,就是每次都遍历一遍给定的数组nums然后不断累加:

for all num in nums:
    dp[i] += dp[i - num];

所以时间复杂度为O(n*target),空间复杂度为O(target)。

注意此题每个排列就算一种选法,例如[1,2]和[2,1]是两种选法,如果只算一次话那就是一个完全背包问题,可参考我的博客-动态规划之背包问题系列

C++

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        int n = nums.size();
        vector<int>dp(target+1, 0);
        dp[0] = 1;
        for(int i = 1; i <= target; i++){
            for(int &num: nums){
                if(i >= num){
                    // 防止超过INT_MAX溢出
                    if(dp[i] <= INT_MAX - dp[i - num])
                        dp[i] += dp[i - num];
                    else dp[i] = INT_MAX;
                }                                        
            }
        }
        return dp[target];
    }
};