LeetCode刷题笔记【29】:动态规划专题-1(斐波那契数、爬楼梯、使用最小花费爬楼梯)

news2024/9/24 5:32:31

文章目录

  • 前置知识
    • 解题思路
    • 解题步骤
    • 动态规划的debug
  • 509. 斐波那契数
    • 题目描述
    • 解题思路
    • 代码
      • 使用dp数组
      • 优化空间复杂度: 不用数组, 只用两个变量记录即可
  • 70. 爬楼梯
    • 题目描述
    • 解题思路
    • 代码
      • 使用dp数组
      • 优化空间复杂度: 不用数组, 只用两个变量记录即可
  • 746. 使用最小花费爬楼梯
    • 题目描述
    • 解题思路
    • 代码
      • 使用dp数组
      • 优化空间复杂度
    • 另一种动态规划思路
  • 总结

前置知识

解题思路

动态规划(DP,Dynamic Programming)。
其解题思路对比贪心算法的“直接选局部最优然后推导出全局最优”;倾向于“由之前的结果推导得到后续的结果”。
很多时候二者具有相似性,不必死扣概念。

解题步骤

动态规划题目的核心是dp数组的概念和构建(递推公式);
所以具体的解题步骤可以分为以下几步:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

动态规划的debug

每走一步都将dp数组打印出来, 检查是否和自己推导和计划的一致.

当出现bug的时候, 思考:

  • 这道题目我举例推导状态转移公式了么?
  • 我打印dp数组的日志了么?
  • 打印出来了dp数组和我想的一样么?

参考文章:动态规划理论基础

509. 斐波那契数

题目描述

在这里插入图片描述

LeetCode链接:https://leetcode.cn/problems/fibonacci-number/description/

解题思路

因为是简单题, 所以直接给出了递推公式, 我们只需要先构建dp数组的前两项, 然后依次向后传递推导即可.

代码

使用dp数组

class Solution {
public:
    int fib(int n) {
        vector<int> fei;
        fei.push_back(0);
        fei.push_back(1);
        for(int i=2; i<=n; ++i){
            fei.push_back(fei[i-1] + fei[i-2]);
        }
        return fei[n];
    }
};

优化空间复杂度: 不用数组, 只用两个变量记录即可

class Solution {
public:
    int fib(int n) {
        if(n==0)    return 0;
        else if(n==1)   return 1;
        int first=0, second=1;
        for(int i=2; i<=n; ++i){
            int tmp = first + second;
            first = second;
            second = tmp;
        }
        return second;
    }
};

70. 爬楼梯

题目描述

截图

LeetCode链接:https://leetcode.cn/problems/climbing-stairs/description/

解题思路

本质上和前一题的斐波那契数列是一样的.

发现第i阶的可能性, 是i-1阶和i-2阶的和
可以理解为: 从i-1阶和i-2阶都可以直接到达i阶, 所以dp[i]=dp[i-1]+dp[i-2]

代码

使用dp数组

class Solution {
public:
    int climbStairs(int n) {
        vector<int> dp;
        dp.push_back(1);
        dp.push_back(1);
        for(int i=2; i<=n; i++){
            dp.push_back(dp[i-1] + dp[i-2]);
        }
        return dp[n];
    }
};

优化空间复杂度: 不用数组, 只用两个变量记录即可

class Solution {
public:
    int climbStairs(int n) {
        if(n==0 || n==1)    return 1;
        int first=1, second=1;
        for(int i=2; i<=n; i++){
            int tmp = first+second;
            first = second;
            second = tmp;
        }
        return second;
    }
};

746. 使用最小花费爬楼梯

题目描述

截图

LeetCode链接:https://leetcode.cn/problems/min-cost-climbing-stairs/description/

解题思路

思路: 动态规划
dp[i] 表示从i处起跳的话, 需要支付的费用
那么就有: dp[i] = min(dp[i-1], dp[i-2]) + cost[i];

代码

使用dp数组

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n=cost.size();
        vector<int> dp(n);
        dp[0] = cost[0];
        dp[1] = cost[1];
        for(int i=2; i<n; ++i){
            dp[i] = min(dp[i-1], dp[i-2]) + cost[i];
        }
        return min(dp[n-1], dp[n-2]);
    }
};

优化空间复杂度

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n=cost.size();
        int first = cost[0];
        int second = cost[1];
        for(int i=2; i<n; ++i){
            int tmp = min(first, second) + cost[i];
            first = second;
            second = tmp;
        }
        return min(first, second);
    }
};

另一种动态规划思路

用另一种思路来构建dp数组:
刚才认为"dp[i]是从i处起跳需要支付的代价", 现在认为"dp[i]是到达i需要支付的代价"
递推公式也就变为: dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);

所以最开始的dp[0]dp[1]初始化为0, dp的长度也设置为cost.size()+1, 一路推导到dp[cost.size()], 直接return即可

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()];
    }
};

总结

本文参考:
斐波那契数
爬楼梯
使用最小花费爬楼梯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/986140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis传递实体对象只能直接获取,不能使用对象.属性方式获取

mybatis的自动识别参数功能很强大&#xff0c;pojo实体类可以直接写进mapper接口里面&#xff0c;不需要在mapper.xml文件中添加paramType,但是加了可以提高mybatis的效率 不加Param注解&#xff0c;取值的时候直接写属性 //这里是单参数&#xff0c;可以不加param&#xff01…

YOLO的基本原理详解

YOLO介绍 YOLO是一种新的目标检测方法。以前的目标检测方法通过重新利用分类器来执行检测。与先前的方案不同&#xff0c;将目标检测看作回归问题从空间上定位边界框&#xff08;bounding box&#xff09;并预测该框的类别概率。使用单个神经网络&#xff0c;在一次评估中直接…

ARM的异常处理

概念 处理器在正常执行程序的过程中可能会遇到一些不正常的事件发生 这时处理器就要将当前的程序暂停下来转而去处理这个异常的事件 异常事件处理完成之后再返回到被异常打断的点继续执行程序 异常处理机制 不同的处理器对异常的处理的流程大体相似&#xff0c;但是不同的处理器…

VsCode备忘

上次简单学习了一下vscode的使用&#xff0c;结果好长时间没用&#xff0c;今天打开又全忘了。。。再记录一下吧 快捷键 CtrlShiftP 命令面板&#xff0c;查找命令&#xff0c;设置等等 Ctrl 打开集成终端&#xff0c;监视生成输出 Ctrl, 打开设置 CtrlP 转到文件,使用转到符…

提高使用VS Code工作效率的技巧

提高使用VS Code工作效率的技巧 时间轴视图&#xff1a;本地源代码控制 时间轴视图为我们提供了内置的源代码控制。 我们中的许多人都知道 Git 和其他源代码控制工具有多么有用&#xff0c;它们可以帮助我们轻松跟踪文件更改并在需要时恢复到之前的状态。 因此&#xff0c;…

网络威胁防御+资产测绘系统-Golang开发

NIPS-Plus 网络威胁防御资产测绘系统-Golang开发 项目地址&#xff1a;https://github.com/jumppppp/NIPS-Plus NIPS-Plus 是一款使用golang语言开发的网络威胁防御系统&#xff08;内置资产测绘系统&#xff09; 网络威胁流量视图网络威胁详细信息浏览列表网络威胁反制探测攻…

编程中的信号处理和系统 - 初学者指南

信号处理是工程和编程的一个重要领域。 基本上,它允许工程师和程序员改进数据,以便人们可以更有效地使用它。 例如,由于信号处理,电话中的大部分背景噪音都被消除了。这样,通话的另一端就只能听到您的声音。 其他例子有: 音频和音乐软件图像视频处理软件医学影像软件语…

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码 1 题目 题目 D 题 圈养湖羊的空间利用率 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&a…

微信小程序navigateTo进入页面后返回原来的页面需要携带数据回来

需求 如图&#xff1a;点击评论后会通过wx.navigateTo进入到评论页面&#xff0c;评论完返回count给原页面&#xff0c;重新赋值实现数量动态变化&#xff0c;不然要刷新这个页面才会更新最新的评论数量。 实现方式&#xff1a; 在评论页面通过wx.setStorageSync(‘data’…

上传ipa到appstore工具

登录app store connect上架的时候&#xff0c;苹果推荐了三个上传构建版本的工具&#xff0c;一个是xcodde&#xff0c;一个是transporter&#xff0c;一个是命令行工具。但是这几个工具在windows都没有对应的软件可以安装。 因此&#xff0c;假如使用windows电脑&#xff0c;…

1600*C. Maximum Set

解析&#xff1a; 尽可能的增大集合内的数&#xff0c;所以倍数要尽可能的小&#xff0c;所以让最小的数不断乘 2&#xff0c;即可找到最大的数量。 所以&#xff0c;每次计算 k log2&#xff08; y / x &#xff09;,这样可得出最小的 x&#xff0c;乘多少个 2&#xff0c;能…

数据分享|WEKA信贷违约预测报告:用决策树、随机森林、支持向量机SVM、朴素贝叶斯、逻辑回归...

完整报告链接&#xff1a;http://tecdat.cn/?p28579 作者&#xff1a;Nuo Liu 数据变得越来越重要&#xff0c;其核心应用“预测”也成为互联网行业以及产业变革的重要力量。近年来网络 P2P借贷发展形势迅猛&#xff0c;一方面普通用户可以更加灵活、便快捷地获得中小额度的贷…

【css面试题】 实现一个盒子的水平竖直居中对齐效果

面试题里有时还会强调 子盒子宽高是否已知&#xff0c;要注意一下 尝试一&#xff1a;给父盒子设置padding 或者子盒子设置margin <style>.father{width: 300px;height: 200px;overflow: hidden; /* 放坑爹现象&#xff0c;不信你删了试试 */background-color: #db7b7b…

SpringBoot隐藏文件

1.设置 2.输入file Types 3.点击忽略文件或者文件夹 4.成功

软件评测师 - 软件测试过程与管理

1.1 软件测试过程 软件的测试过程一般分成测试计划、测试设计与开发、测试实施、测试评审与测试结论等阶段。 软件测试过程是一种抽象的、遵循 GB/T18905&#xff08;ISO14598.5&#xff09;《评价者用的过程&#xff08;Process for Evaluator&#xff09;》 中定义软件评价过…

redis集群架构详解

一、集群架构搭建 1、配置 在一台机器上模拟多台机器搭建redis集群&#xff0c;一个集群代表一台物理机 集群1路径&#xff1a; /usr/local/redis/redis-cluster/cluster1/9001/redis.conf/usr/local/redis/redis-cluster/cluster1/9004/redis.conf/usr/local/redis/redis-…

算法通关村第12关【黄金】| 字符串冲刺题

1.最长公共前缀 思路&#xff1a;纵向比较&#xff0c;每个字符串从头挨个比较 class Solution {public String longestCommonPrefix(String[] strs) {StringBuilder sb new StringBuilder();for(int i 0;i<strs[0].length();i){char c strs[0].charAt(i);for(int j 1;j…

Android Framework开发rom实战合集课表/车载车机手机高级系统开发工程必会技能

hi,粉丝朋友&#xff1a; 背景 android framework的初级学习者们&#xff0c;这里大部分是app的开发者想转framework开发&#xff0c;普遍有以下以下几个困惑痛点&#xff1a; 1、不知道framework学了可以干啥&#xff0c;以为学习framework就是看看源码梳理流程而已没有实际…

蠕虫病毒问题

蠕虫病毒处理过程 修改病毒定时时间&#xff0c;今天遇到的是 */30 crontab -e先修改延长时间&#xff0c;会提示无操作权限,执行下面的问题 chattr -l /filepath查看可疑进程&#xff0c;这次遇到的进程有 /tmp/***** /tmp/crontab***** ps -auxkill -9 相关进程 删除/…