377. Combination Sum IV
思路:
类似完全背包问题,但是背包问题求的是组合,这里求的是排列。区别为,例如{1,3},组合只有{1,3},而排列有{1,3}和{3,1}.
而组合和排列的转换可通过两个for循环,如果背包容量的for在外,物品的for在里,那么就可以得到排列。相反就得到组合的排列。
在这道题,0-target就是背包容量,nums数组就是物品。
用动态规划我们就能用前部得到的结果转移为现在元素的结果。那么对于i背包容量来说,我们每次都遍历所有的物品num,然后加上从i-num>=0的背包容量装上的物品,那么当nums遍历完,我们就得到i容量能装的物品的排列数了。
因此我们对于dp数组,定义dp[i]为 背包容量为i时能装的物品的排列总数,也即总和为i时,
代码:
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target+1);
dp[0]=1; //边界条件,可以理解当背包容量为0时,什么都不取,就是一个方案。
for(int i=0;i<=target;++i){
for(int num:nums){
if(i-num>=0&&dp[i]<INT_MAX-dp[i-num]){ //需要限制dp超过int限制 dp[i]+dp[i-num]<INT_MAX
dp[i] += dp[i-num];
}
}
}
return dp[target];
}
};