算法训练day38动态规划基础Leetcode509斐波纳切数70爬楼梯746使用最小花费爬楼梯
什么是动态规划
对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组(打印dp数组)
找问题的最好方式就是把dp数组打印出来,看看究竟是不是按照自己思路推导的!
做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果。
509 斐波那契数
题目描述
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。
示例 1:
输入:n = 2 输出:1 解释:F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2:
输入:n = 3 输出:2 解释:F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3:
输入:n = 4 输出:3 解释:F(4) = F(3) + F(2) = 2 + 1 = 3
提示:
0 <= n <= 30
题目分析
就像二叉树三部曲
-
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
-
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
-
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
是有方法论的
这里动规五步曲也是一样
acm模式代码
#include <iostream>
#include <vector>class Solution {
public:int fib(int n) {std::vector<int> dp(n + 1);if (n <= 0) {return 0;}else if (n == 1) {return 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];}
};int main() {Solution sol;int n = 5;int sum = sol.fib(n);std::cout << n << "sum:" << sum << std::endl;return 0;
}
70. 爬楼梯
题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶
示例 2:
输入:n = 3 输出:3 解释:有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 + 1 阶 2. 1 阶 + 2 阶 3. 2 阶 + 1 阶
提示:
1 <= n <= 45
题目分析
爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。
那么第一层楼梯再跨两步就到第三层 ,第二层楼梯再跨一步就到第三层。
所以到第三层楼梯的状态可以由第二层楼梯 和 到第一层楼梯状态推导出来,那么就可以想到动态规划了。
acm模式代码
#include <iostream>
#include <vector>class Solution {
public:int climbStairs(int n) {if (n <= 1) return n;std::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];}
};int main() {Solution sol;int n = 5;int sum = sol.climbStairs(n);std::cout << n << "sum:" << sum << std::endl;return 0;
}
746使用最小花费爬楼梯
题目描述
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20] 输出:15 解释:你将从下标为 1 的台阶开始。 - 支付 15 ,向上爬两个台阶,到达楼梯顶部。 总花费为 15 。
示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1] 输出:6 解释:你将从下标为 0 的台阶开始。 - 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。 - 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。 - 支付 1 ,向上爬一个台阶,到达楼梯顶部。 总花费为 6 。
提示:
2 <= cost.length <= 10000 <= cost[i] <= 999
题目分析
- 确定dp数组以及下标的含义
使用动态规划,就要有一个数组来记录状态,本题只需要一个一维数组dp[i]就可以了。
dp[i]的定义:到达第i台阶所花费的最少体力为dp[i]。
对于dp数组的定义,大家一定要清晰!
- 确定递推公式
可以有两个途径得到dp[i],一个是dp[i-1] 一个是dp[i-2]。
dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1]。
dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。
那么究竟是选从dp[i - 1]跳还是从dp[i - 2]跳呢?
一定是选最小的,所以dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
- dp数组如何初始化
看一下递归公式,dp[i]由dp[i - 1],dp[i - 2]推出,既然初始化所有的dp[i]是不可能的,那么只初始化dp[0]和dp[1]就够了,其他的最终都是dp[0]dp[1]推出。
那么 dp[0] 应该是多少呢? 根据dp数组的定义,到达第0台阶所花费的最小体力为dp[0],那么有同学可能想,那dp[0] 应该是 cost[0],例如 cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 的话,dp[0] 就是 cost[0] 应该是1。
这里就要说明本题力扣为什么改题意,而且修改题意之后 就清晰很多的原因了。
新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的,但从 第0 个台阶 往上跳的话,需要花费 cost[0]。
所以初始化 dp[0] = 0,dp[1] = 0;
- 确定遍历顺序
最后一步,递归公式有了,初始化有了,如何遍历呢?
本题的遍历顺序其实比较简单,简单到很多同学都忽略了思考这一步直接就把代码写出来了。
acm模式代码
#include <iostream>
#include <vector>
#include <algorithm>class Solution {
public:int minCostClimbingStairs(std::vector<int>& cost) {std::vector<int> dp(cost.size() + 1);// dp[i]的定义:到达第i台阶所花费的最少体力为dp[i]。dp[0] = 0;dp[1] = 0;int sum = 0;for (int i = 2; i <= cost.size(); i++) {dp[i] = std::min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);}// for (int i : dp) {// std::cout << i << " ";// }// std::cout << std::endl;// return dp.back();return dp[cost.size()];}
};int main() {std::vector<int> count = {1, 100, 1, 1, 1, 100, 1, 1, 100, 1};Solution sol;int min = sol.minCostClimbingStairs(count);std::cout << "sum: " << min << std::endl;
}
相关文章:
算法训练day38动态规划基础Leetcode509斐波纳切数70爬楼梯746使用最小花费爬楼梯
什么是动态规划 对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了! 确定dp数组(dp table)以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组&a…...
Leetcode 206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:head [1,2] 输出:[2,1] 示例 3: 输…...
电子科技大学课程《计算机网络系统》(持续更新)
前言 本校的课程课时有所缩减,因此可能出现与你学习的课程有所减少的情况,因此对其他学校的同学更多的作为参考作用。本文章适合学生的期中期末考试,以及想要考研电子科技大学的同学,电子科技大学同学请先看附言。 第一章 计算…...
HBase介绍、特点、应用场景、生态圈
目录: 一、HBase简介 二、NoSQL和关系型数据库对比 三、HBase特点 四、应用场景 五、HBase生态圈技术 一、HBase简介 HBase是一个领先的NoSQL数据库 是一个面向列存储的NoSQL数据库 是一个分布式Hash Map,底层数据是Key-Value格式 基于Coogle Big Table论文 使用HD…...
蓝桥杯错误记录
今天在做 小蜜蜂的综合案例的时候,数码管显示,有重影。 #include <STC15F2K60S2.H> unsigned char num; unsigned char code Duan[22]{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80, 0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0XC1,0X8C,0…...
Spring-静态代理VS动态代理/实现代理ProxyFactory
文章目录 静态代理VS动态代理Spring实现代理ProxyFactory 工作中遇到问题整理动态代理异常com.sun.proxy.$Proxy0 cannot be cast to 静态代理VS动态代理 静态代理VS动态代理 参考URL: https://blog.csdn.net/qq_25881443/article/details/103245938 【java项目实战】代理模式…...
单片机精进之路-9ds18b20温度传感器
ds18b20复位时序图,先将b20的数据引脚拉低至少480us,然后再将数据引脚拉高15-60us,再去将测传感器的数据引脚是不是变低电平并保持60-240us,如果是,则说明检测到温度传感器,并正常工作。需要在240us后才能检…...
支部管理系统微信小程序(管理端+用户端)flask+vue+mysql+微信小程序
系统架构如图所示 高校D支部管理系统 由web端和微信小程序端组成,由web端负责管理,能够收缴费用、发布信息、发布问卷、发布通知等功能 部分功能页面如图所示 微信小程序端 包含所有源码和远程部署,可作为毕设课设...
4、Linux-常用命令(二)
目录 一、搜索命令 1、命令搜索命令 2、文件搜索命令find。格式:find [搜索范围] [搜索条件]。 3、字符串搜索命令grep 二、帮助命令 1、man【详细的帮助】 2、--help【简要的帮助】 三、压缩与解压命令 1、.zip格式 2、.gz格式 3、打包 四、关机和重启命…...
golang实现openssl自签名双向认证
第一步:生成CA、服务端、客户端证书 1. 生成CA根证书 生成CA证书私钥 openssl genrsa -out ca.key 4096创建ca.conf 文件 [ req ] default_bits 4096 distinguished_name req_distinguished_name[ req_distinguished_name ] countryName …...
【学习】torchvision.datasets.ImageFolder()
在分类任务中,数据集文件存储往往是如下形式: - train- class1- image1.jpg- image2.jpg...- class2- image1.jpg- image2.jpg......此时,我们想要获取图片和标签,标签即为文件名(class1、class2…) 可以使…...
pyinstaller打包的exe运行报错 No module named path
描述 用python开发了一个opc client应用,调试没有问题后,使用pyinstaller打包成exe,测试exe运行也没有问题,正常使用。 在某次重装win10系统后,在此运行exe就开始报错了,详细内容如下: ------…...
Vue3中Vuex状态管理库学习笔记
1.什么是状态管理 在开发中,我们会的应用程序需要处理各种各样的数据,这些数据需要保存在我们应用程序的某个位置,对于这些数据的管理我们就称之为状态管理。 在之前我们如何管理自己的状态呢? 在Vue开发中,我们使用…...
React富文本编辑器开发(二)
我们接着上一节的示例内容,现在有如下需求,我们希望当我们按下某个按键时编辑器有所反应。这就需要我们对编辑器添加事件功能onKeyDown, 我们给 Editor添加事件: SDocor.jsx import { useState } from react; import { createEditor } from…...
nginx代理minio客户端
错误方式 在点击桶名查看文件时, 会一直处于loading加载中 worker_processes 1; #设置 Nginx 启动的工作进程数为 1。events {worker_connections 1024; ##设置每个工作进程的最大并发连接数为 1024。 }http {include mime.types; #该文件定义了文件扩展名和 MIME 类型…...
将ppt里的视频导出来
将ppt的后缀从pptx改为zip 找到【media】里面有存放图片和音频以及视频,看文件名后缀可以找到,mp4的即为视频,直接复制粘贴到桌面即可。 关闭压缩软件把ppt后缀改回,不影响ppt正常使用。...
Spring Boot 3核心技术与最佳实践
💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 highlight: a11y-dark 引言 Spring Boot作为…...
redis缓存更新策略
更新缓存策略: 对于低一致性需求的业务:使用redis自带的内存淘汰机制就行了,自动失效,等查询时再更新。 对于高一致性需求的业务:推荐主动更新,由缓存的调用者更新数据库的同时更新缓存(删除缓存)。 这里的…...
【操作系统学习笔记】文件管理1.4
【操作系统学习笔记】文件管理1.4 参考书籍: 王道考研 视频地址: Bilibili 文件的物理结构 文件快、磁盘块 在内存管理中,进程的逻辑空间被分为一个一个页面。同样的,在外存管理中,为了方便对文件数据的管理,文件的逻辑地址空…...
快递包装展|2024上海国际电商物流包装产业展览会
2024中国(上海)国际电商物流包装产业展览会 2024 China (Shanghai) international e-commerce logistics packaging industry exhibition 时 间:2024年7月24日 —7月26日 地 点:国家会展中心(上海市青浦区崧泽大道333号ÿ…...
无数据库版Mirror照妖镜源码解析:如何安全改造为个人图片鉴黄工具
无数据库版Mirror照妖镜源码解析:如何安全改造为个人图片鉴黄工具 在当今内容爆炸的时代,图片审核成为许多个人开发者和内容创作者的刚需。传统解决方案往往依赖复杂的数据库系统和第三方API,而Mirror照妖镜的无数据库设计为轻量级图片审核提…...
如何通过AndroidAnnotations与Kotlin扩展函数实现极速Android开发:新手必备指南
如何通过AndroidAnnotations与Kotlin扩展函数实现极速Android开发:新手必备指南 【免费下载链接】androidannotations Fast Android Development. Easy maintainance. 项目地址: https://gitcode.com/gh_mirrors/an/androidannotations AndroidAnnotations是…...
【Python内存管理2026权威白皮书】:GIL演进、引用计数重构与GC智能调度三大突破性策略首次公开
第一章:Python智能体内存管理策略2026最新趋势全景概览随着大语言模型驱动的Python智能体(Agent)在生产环境中的深度部署,传统CPython内存管理机制正面临前所未有的挑战:动态工具调用、多轮推理缓存、跨Agent状态共享及…...
MacBook Intel芯片用户看过来:保姆级Anaconda安装与国内镜像源配置全攻略
MacBook Intel芯片用户看过来:保姆级Anaconda安装与国内镜像源配置全攻略 作为一名长期使用MacBook进行Python开发的工程师,我深知环境配置对于初学者来说可能是个不小的挑战。特别是对于使用Intel芯片的MacBook用户,虽然相比M1芯片少了些兼容…...
OpenClaw浏览器自动化:ollama-QwQ-32B驱动的研究资料收集系统
OpenClaw浏览器自动化:ollama-QwQ-32B驱动的研究资料收集系统 1. 为什么需要自动化研究资料收集 作为一名经常需要查阅大量文献的技术写作者,我长期被资料收集的效率问题困扰。传统工作流程中,我需要手动在Google Scholar、arXiv、知乎等平…...
避开这些坑!群晖+acme.sh申请Let’s Encrypt证书的完整指南
群晖NAS上零踩坑申请Lets Encrypt证书的终极实践手册 每次看到浏览器地址栏那个刺眼的"不安全"提示就浑身难受?作为群晖深度用户,我花了三个周末时间踩遍了所有证书申请的坑。从idn指令缺失到nss验证失败,从API调用超时到证书自动更…...
零基础玩转OpenClaw:Qwen3-32B-Chat镜像云端体验指南
零基础玩转OpenClaw:Qwen3-32B-Chat镜像云端体验指南 1. 为什么选择云端体验OpenClaw? 第一次听说OpenClaw时,我正被各种本地部署的依赖项折磨得焦头烂额。作为一个习惯在MacBook上写代码的开发者,光是配置CUDA环境就让我望而却…...
pykg2vec功能mastery:知识图谱嵌入模型的高级配置与优化
pykg2vec功能mastery:知识图谱嵌入模型的高级配置与优化 【免费下载链接】pykg2vec 项目地址: https://gitcode.com/gh_mirrors/py/pykg2vec 问题导入 知识图谱嵌入模型训练中,开发者常面临三大痛点:模型参数调优耗时且效果不佳、不…...
Zotero终极指南:高效文献管理的开源解决方案
Zotero终极指南:高效文献管理的开源解决方案 【免费下载链接】zotero Zotero is a free, easy-to-use tool to help you collect, organize, annotate, cite, and share your research sources. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero Zotero是…...
大模型进阶:掌握Function Calling和MCP,解锁AI生产力(收藏版)
本文深入探讨了Function Calling技术如何帮助大模型获取实时信息、执行任务,以及MCP协议在大模型与外部交互中的关键作用。文章阐述了从提示工程到RAG,再到Function Calling和MCP的技术演进路径,强调了这些技术如何使大模型从信息工具转变为生…...
