主要思路:
复盘之前写的一道题,不过这次是用完全背包的思路
易错点:
本题dp[ i ]表示的是台阶为i的排序数
代码实现:
class Solution {
public:
int climbStairs(int n) {
vector<int> dp(n + 1, 0);
dp[0] = 1;
for(int j = 1; j < dp.size(); j++) {
for(int i = 1; i <= 2; i++) {
if(j >= i) dp[j] += dp[j - i];
}
}
return dp[n];
}
};
主要思路:
(1)dp[ i ]数组含义:装满容量为 i 的钱包的最小硬币数
(2)递推公式:dp[j] = min(dp[j], dp[j - coins[i]] + 1);
(3)初始化:dp[0] = 0,其他初始化为INT_MAX - 1
(4)遍历顺序:先遍历物品再遍历背包,从前往后
代码实现:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX - 1);
dp[0] = 0;
for(int i = 0; i < coins.size(); i++) {
for(int j = coins[i]; j < dp.size(); j++) {
dp[j] = min(dp[j], dp[j - coins[i]] + 1);
}
}
int ret = -1;
if(dp[amount] < INT_MAX - 1) ret = dp[amount];
return ret;
}
};
主要思路:
与上面零钱基本一致,不同之处在于本题一定可以凑出(用1凑),所以本题初始化时都初始化为下标
代码实现:
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n + 1);
dp[0] = 0;
for(int i = 1; i < dp.size(); i++) {
dp[i] = i;
}
for(int i = 1; i * i <= n; i++) {
for(int j = i * i; j < dp.size(); j++) {
dp[j] = min(dp[j], dp[j - i * i] + 1);
}
}
return dp[n];
}
};