算法刷题 Day 45 | ● 70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数

70. 爬楼梯 (进阶)

这道题目 爬楼梯之前我们做过,这次再用完全背包的思路来分析一遍

https://programmercarl.com/0070.%E7%88%AC%E6%A5%BC%E6%A2%AF%E5%AE%8C%E5%85%A8%E8%83%8C%E5%8C%85%E7%89%88%E6%9C%AC.html

Tips:

改为:一步一个台阶,两个台阶,三个台阶,.......,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢?

1阶,2阶,.... m阶就是物品,楼顶就是背包。

每一阶可以重复使用,例如跳了1阶,还可以继续跳1阶。

问跳到楼顶有几种方法其实就是问装满背包有几种方法。

此时大家应该发现这就是一个完全背包问题了!

我的题解:

class Solution {
public:
    int climbStairs(int n) {
        // 完全背包版代码
        vector<int> dp(n+1,0);
        dp[0] = 1;
        for(int i = 1; i<=n; i++){
            for(int j = 1; j<=2; j++){
                if(i>=j){
                    dp[i] += dp[i-j];
                }
            }
        }
        return dp[n];
    }
};

322. 零钱兑换

如果求组合数就是外层for循环遍历物品,内层for遍历背包。

如果求排列数就是外层for遍历背包,内层for循环遍历物品。

这句话结合本题 大家要好好理解。

视频讲解:https://www.bilibili.com/video/BV14K411R7yv

https://programmercarl.com/0322.%E9%9B%B6%E9%92%B1%E5%85%91%E6%8D%A2.html

Tips:想好思路后写出代码,就很简单了。

本题求钱币最小个数,那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数

所以本题并不强调集合是组合还是排列。

我的题解:

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

279.完全平方数

本题 和 322. 零钱兑换 基本是一样的,大家先自己尝试做一做

视频讲解:https://www.bilibili.com/video/BV12P411T7Br

https://programmercarl.com/0279.%E5%AE%8C%E5%85%A8%E5%B9%B3%E6%96%B9%E6%95%B0.html

Tips:要记得初始化dp[0]啊,同时代码中进行了一个剪枝的操作

我的题解:

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n+1,INT_MAX);
        dp[0] = 0;
        for(int i = 0; i <= n/2 + 1; i++){ // 这里有剪枝,+1是为了n = 1的情况
            for(int j = i*i; j<=n; j++){
                if(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];
    }
};

 

posted @ 2023-02-20 16:16  GavinGYM  阅读(42)  评论(0)    收藏  举报