LC 70. 爬楼梯 (进阶)
题目链接:LC 70. 爬楼梯 (进阶)
思路:之前本题是按着斐波那契数列的思路来求解的,和上一章节中的组合数联系,可看到这两道题的本质是相同的,总阶数就是我们的target,每步走1或者2步就是数组中的值。基于dp,我们还可以求解m步到楼梯顶的方式。
代码:
class Solution {
public:
//走到1,有1中走法;走到2,有两种走法;走到3可以从1或者2开始走,有1+2 = 3种走法,因为从2开始的包括1+1+1了,所以从1开始到3的只有1+2一种;同样到4有3+2=5种走法
// int climbStairs(int n) {
// vector<int> nums(n);
// if(n<=3){
// return n;
// }
// nums[0] = 1;
// nums[1] = 2;
// for(int i=2; i<n; i++){
// nums[i] = nums[i-1]+nums[i-2];
// }
// return nums[n-1];
// }
int climbStairs(int n) {
vector<int> dp(n+1, 0);
dp[0] = 1;
vector<int> nums(2);
nums[0] = 1;
nums[1] = 2;
for(int i=1; i<n+1; i++){//遍历楼梯
for(int j=0; j<2; j++){//遍历步数
if(i-nums[j]>=0)
dp[i] += dp[i-nums[j]];
}
}
return dp.back();
}
};
LC 322. 零钱兑换
题目链接:LC 322. 零钱兑换
思路:完全背包,dp数组内的值dp[i][j]表示得到j用第0-i个值至少用几个数,因此它的更新公式是求最小值,所以需要将其初始化为最大值,而dp数组的第0个值初始化为0,因为后面需要对其加1.
代码:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
if(amount==0)return 0;
vector<int> dp(amount+1, INT_MAX);
dp[0] = 0;
for(int i=0; i<coins.size(); i++){
for(int j=coins[i]; j<amount+1; j++){
if(dp[j-coins[i]]==INT_MAX)continue;
else dp[j] = min(dp[j],dp[j-coins[i]]+1);
}
}
if(dp.back()==INT_MAX)return -1;
else return dp.back();
}
};
LC 279.完全平方数
题目链接:LC 279.完全平方数
思路:思路与上一题相同,但是需要自己创建nums数组。
代码:
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n+1, INT_MAX);
dp[0] = 0;
//创建数组
vector<int> nums(1,1);
int k = 2;
while(true){
int cur = k*k;
k++;
if(cur<=n){
nums.push_back(cur);
}
else break;
}
for(int i=0; i<nums.size(); i++){
for(int j=nums[i]; j<n+1; j++){
if(dp[j-nums[i]]!=INT_MAX)dp[j] = min(dp[j], dp[j-nums[i]]+1);
}
}
return dp.back();
}
};