两个for循环:
先遍历(物品i),再遍历背包(j)得到的是组合数
先遍历背包(j),再遍历(物品i)得到的是排列数;
518. 零钱兑换 II
知识点:动规
状态:没懂,需要重新看
思路:
没懂
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount+1,0); // dp[j]是金额为j的组合数
sort(coins.begin(), coins.end());
if(coins[0] > amount) return 0;
dp[0] = 1; // huozhe 1
for(int i = 0; i < coins.size(); i ++){
for(int j = coins[i] ; j < amount+1; j++ ) {
dp[j] = dp[j] + dp[j - coins[i]];
}
}
return dp[amount] ;
}
};
377. 组合总和 Ⅳ
知识点:动规
状态:没懂,需要重新看,尤其是限制条件
思路:没懂
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> 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] < INT_MAX - dp[i - nums[j]]) {
// 仅有当剩余容量大于当前要加进去的物品i
// C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
};