103)最少的硬币数目
class Solution{
public:
int coinChange(vector<int>& coins, int amount){
vector<int> dp(amount+1, amount+1);
dp[0]=0;
for(int i=1; i<=amount; i++){
for(int coin : coins){
if(i>=coin){
dp[i] = min(dp[i], dp[i-coin]+1);
}
}
}
return dp[amount]==amount+1 ? -1 : dp[amount];
}
};
104)排列的数目
class Solution{
public:
int combinationSum4(vector<int>&nums, int target){
int n = nums.size();
vector<long> dp(target+1);
dp[0] = 1;
for(int i=1; i<=target; i++){
for(int num : nums){
if(i >= num){
dp[i] += dp[i-num];
dp[i] %= INT_MAX;
}
}
}
return dp[target];
}
};
关键点:1.若数组中元素不允许重复使用,则在遍历target的时候,从大到小遍历;
2.若考虑组合的顺序问题,则需要先遍历target,再遍历nums,这样可以保证不同顺序下的组合都可以保留!
小Tips:设dp注意int超过INT_MAX,用INT_MAX取余
先遍历背包容量,后遍历物品:则可以遍历所有的顺序不同的组合
先遍历物品,后遍历背包容量:则可以从前到后序的所有唯一组合数