代码随想录算法训练营第28天|动态规划理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

动态规划理论基础

2025-02-28 22:49:46 星期五

代码随想录视频内容简记

动态规划的常见类型

  1. 动态规划基础,比如斐波那契数列

  2. 背包问题

  3. 打家劫舍

  4. 股票问题

  5. 子序列问题

动态规划五部曲

  1. dp数组的定义

  2. 递推公式

  3. dp数组初始化

  4. 遍历顺序

  5. 打印dp数组

LeetCode509

题目描述:力扣509
文档讲解:代码随想录(programmercarl)509. 斐波那契数
视频讲解:《代码随想录》算法视频公开课:手把手带你入门动态规划 | leetcode:509.斐波那契数

代码随想录视频内容简记

可以按照动归五部曲来进行分析

梳理

  1. 确定dp数组的含义,本题中dp[i]数组就代表第i个斐波那契数列的值

  2. 递推公式。就是dp[i] = dp[i - 1] + dp[i - 2]

  3. dp数组初始化。dp[0] = 1, dp[1] = 1

  4. 遍历顺序,从前向后

  5. 打印dp数组,可以直接return

LeetCode测试

注意,这里如果不加上if (n <= 1) return n;,那么在执行之后会报错

因为在定义dp数组的时候只有dp(n + 1);,出现n = 0的时候只会有1个数组的长度,所以dp[1] = 1;就会报错


正确代码如下

点击查看代码
class Solution {
public:
    int fib(int n) {
        if (n <= 1) return n;
        vector<int> dp(n + 1);
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

LeetCode70

题目描述:力扣70
文档讲解:代码随想录(programmercarl)70. 爬楼梯
视频讲解:《代码随想录》算法视频公开课:带你学透动态规划-爬楼梯|LeetCode:70.爬楼梯)

梳理

按照动归五部曲来做

  1. 确定dp[i]的含义:表示第i阶楼梯有dp[i]种方式

  2. 确定递归公式:这个题递推公式就是斐波那契数列。

    第1阶:1种
    第2阶:2种
    第3阶:从第1阶直接上来,从第2阶直接上来。1+2=3
    ......
    dp[i] = dp[i - 1] + dp[i - 2]

  3. dp[i]数组初始化。dp[0]是没有意义的,从dp[1] = 1, dp[2] = 2

  4. 遍历顺序,从前向后

  5. 打印dp[i]数组

LeetCode测试

这个需要注意的,就是如果i = 0没有意义,那么for循环初始化就得从i = 3开始了

点击查看代码
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 2) return n;
        vector<int> dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

LeetCode746

题目描述:力扣746
文档讲解:代码随想录(programmrcarl)746. 使用最小花费爬楼梯
视频讲解:《代码随想录》算法视频公开课::动态规划开更了!| LeetCode:746. 使用最小花费爬楼梯

代码随想录视频内容简记

这个题有三个需要注意的点:

  1. 题目描述中说:你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。那么从0或者1开始是没有花费的

  2. 站在一个楼梯上并没有花费,只要选择往上跳了,才有花费

  3. 关于楼梯顶部,给定一个楼梯,[10,15,20]。下标分别是0,1,2,楼梯顶部的下标应该是3

梳理

  1. 确定dp[i]数组的含义,是到达第i个楼梯最小花费dp[i]

  2. 确定递归公式。因为可以选择一次跳一个或者两个台阶,所以找的应该是dp[i],dp[i - 1],dp[i - 2]三者之间的关系。其次是关于cost,因为要到达dp[i],dp[i - 1]和dp[i - 2]还需要加上他们自身的花费,所以应该是dp[i - 1] + cost[i - 1]dp[i - 2] + cost[i - 2]那么三者之间的关系应该选择最小,也就是min

  3. 初始化dp数组,dp[0]和dp[1]都是花费为0

  4. 确定遍历顺序,从前向后

  5. 打印dp数组

LeetCode测试

点击查看代码
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        vector<int> dp(cost.size() + 1);
        dp[0] = 0;
        dp[1] = 0;
        for (int i = 2; i <= cost.size(); i++) {
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[cost.size()];
    }
};
posted on   bnbncch  阅读(536)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示