LeetCode 518. 零钱兑换 II
0-1背包每个物品可以重复选取,那么就不能倒序遍历了,要正序遍历,保证前面选过的物品能再次选取
dp[j]的含义为j容量的背包塞满的组合数
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount + 1, 0);
dp[0] = 1;
for(int i = 0; i < coins.size(); i++){
//遍历物品
for(int j = coins[i]; j <= amount; j++){
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
};
LeetCode 377. 组合总和 Ⅳ
这道题也是完全背包,但是求的是组合数
就要先遍历背包容量, 这样在后面遍历物品的时候, 每个物品有不同的排列顺序
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<long> dp(target + 1, 0);
dp[0] = 1;
for(int i = 0; i <= target; i++){
//遍历背包
for(int j = 0; j < nums.size(); j++){
//遍历物品,求排列数量
if(i - nums[j] >= 0 && dp[i] + dp[i - nums[j]] <= INT_MAX){
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
};