算法刷题记录 Day38
Date: 2024.04.04
lc 377. 组合总和IV
实际为排列问题。联想一下爬楼梯问题,若每次能爬1或2格,爬到第n阶的方法数,可以由n-1和n-2推出。该题同理,只是拓展了能爬的距离。
c++
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
int n = nums.size();
// dp[j]表示和为target的排列个数;
vector<int> dp(target+1, 0);
// 到target的方法数,可以由到target-nums[i]的方法数推出来。
dp[0] = 1;
for(int j=1; j<=target; j++){
for(int i=0; i<n; i++){
if(j >= nums[i] && dp[j-nums[i]] < INT_MAX - dp[j]){
dp[j] += dp[j-nums[i]];
}
}
}
return dp[target];
}
};
lc 518. 零钱兑换II
c++
// 一维dp数组,组合问题
class Solution {
public:
int change(int amount, vector<int>& coins) {
int n = coins.size();
// dp[j]表示组成金额为j的硬币组合数有几种;
vector<int> dp(amount+1, 0);
// d[j] = for(i) dp[j] += dp[j-nums[i]];
// 初始化:
dp[0] = 1;
for(int i=0; i<n; i++){
int tmp = coins[i];
for(int j=0; j<=amount; j++){
if(j >= tmp){
dp[j] += dp[j-tmp];
}
}
}
return dp[amount];
}
};
// 二维dp数组,组合问题
class Solution {
public:
int change(int amount, vector<int>& coins) {
int n = coins.size();
// dp[i][j]表示从前i个硬币中,能得到总金额j的总组合数。
vector<vector<int>> dp(n+1, vector<int>(amount+1, 0));
// dp[i][j] = for(i) dp[i-1][j] += dp[i][j-coins[i]];
// 初始化
dp[0][0] = 1;
for(int i=1; i<=n; i++){
for(int j=0; j<=amount; j++){
// cout<<"i:"<<i<<", j:"<<j<<endl;
dp[i][j] = dp[i-1][j];
if(j >= coins[i-1]){
dp[i][j] += dp[i][j-coins[i-1]];
}
}
}
return dp[n][amount];
}
};