70. 爬楼梯(进阶版)

思路:阶梯总数是背包重量,每次几个台阶是物品,求排列总数。

#include <bits/stdc++.h>
using namespace std;
 
void solve(int n, int m){
    vector<int> dp(n + 1);
    dp[0] = 1;
    for (int j = 1; j <= n; j++){
        for (int i = 1; i <= m; i++){
            if (j >= i) dp[j] += dp[j - i];
        }
    }
    cout << dp[n] <<endl;
     
}
 
int main(){
    int n, m;
    cin >> n >> m;
    solve(n, m);
    return 0;
}

Leetcode322. 零钱兑换

思路:dp[j] 代表装满背包的最少硬币数,这里注意:dp[0] = 0,其它值设为INT_MAX,刚好保证背包可以装满。而求排列,组合问题的完全背包也是一样的原理,有有效数值时其背包一定时装满的。另外注意本题的 数值超界。

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i < coins.size(); i++){
            for (int j = 0; j <= amount; j++){
                if (j >= coins[i] && dp[j - coins[i]] != INT_MAX) dp[j] = min(dp[j], dp[j - coins[i]] + 1); 
            }
        }
        if (dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};

Leetcode279.完全平方数

思路:和上一题:322. 零钱兑换 一样的思路。 i * i 当成物品即可。

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++){
                if (j >= i * i && dp[j - i * i] != INT_MAX) dp[j] = min(dp[j], dp[j - i * i] + 1); 
            }
        }
        if (dp[n] == INT_MAX) return -1;
        return dp[n];
    }
};

第四十五天打卡,加油!!!

01-13 06:30