题目
leetcode 377.组合总和 IV 已知:数组nums,目标整数target 现求:nums中元素之和为target的排列数 注意:nums中各元素可多次选取且元素选取顺序也会影响
思路
动态规划
状态
dp[i] : 选取元素之和为i的方案总数 则题目所求目标为dp[target]
转移方程
假设已知dp[i - num],即选取元素之和为i - num 的方案总数,其中num为nums中一个元素。
原总和 = nums[X1] + … + nums[Xn] = i - num
则在原总和末尾加上num,新总和即为i。
新总和 = nums[X1] + … + nums[Xn] + num = i
新末尾num可以是nums中的任意一个小于等于i的元素。 因此遍历nums数组中小于等于i的元素,dp[i] += dp[i - num]
状态转移方程即为dp[i] += dp[i - num]
初始化
当i == 0时,dp[i] = dp[0] = 1,不选取任何元素,元素之和则为0,只有一种方案。 注意:题中给出范围1 <= nums[i] <= 1000
AC代码
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1);
dp[0] = 1;
for(int i = 1; i <= target; i++) {
for(int& num : nums) {
if(num <= i && dp[i - num] < INT_MAX - dp[i])
dp[i] += dp[i - num];
}
}
return dp[target];
}
};
对于以下代码的解释
dp[i - num] < INT_MAX - dp[i]
数值可能会很大,即可能超出数值范围,因此需要规定dp[i - num]的范围。 题中标注的“题目数据保证答案符合 32 位整数范围。“ 是对target的保证
|