当前位置: 首页 > news >正文

​Leetcode 746. 使用最小花费爬楼梯​ 入门dp C++实现

问题:Leetcode 746. 使用最小花费爬楼梯

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

caf88cbd5c1547b5b2c2c8a3dd74da82.png


算法1:递归

        因为要解决的问题都是「从 01 爬到  i 」,所以定义 dfs ( i ) 表示从 01 爬到 i 的最小花费。

枚举最后一步爬了几个台阶,分类讨论:

        如果最后一步爬了 1 个台阶,那么我们得先爬到 i − 1,要解决的问题缩小成:从 01 爬到 i − 1 的最小花费。把这个最小花费加上 cost [ i − 1 ] ,就得到了 dfs ( i ) ,即 dfs ( i ) = dfs ( i − 1 ) + cost [ i − 1 ] 
        如果最后一步爬了 2 个台阶,那么我们得先爬到 i − 2,要解决的问题缩小成:从 01 爬到 i − 2 的最小花费。把这个最小花费加上 cost [ i − 2 ] ,就得到了 dfs ( i ) ,即 dfs ( i ) = dfs ( i − 2 ) + cost [ i − 2 ] 
        这两种情况取最小值,就得到了从 01 爬到 i 的最小花费,即dfs ( i ) = min ( dfs ( i − 1 ) + cost [ i − 1 ] , dfs ( i − 2 ) + cost [ i − 2 ] )
        递归边界:dfs ( 0 ) = 0, dfs ( 1 ) = 0。爬到 01 无需花费,因为我们一开始在 01

        递归入口:dfs ( n ),也就是答案。

代码:

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

算法2:递归 + 记录返回值 = 记忆化搜索

        注意到「先爬 1 个台阶,再爬 2 个台阶」和「先爬 2 个台阶,再爬 1 个台阶」,都相当于爬 3 个台阶,都会从 dfs ( i ) 递归到 dfs ( i  − 3 ) 

        一叶知秋,整个递归中有大量重复递归调用(递归入参相同)。由于递归函数没有副作用,同样的入参无论计算多少次,算出来的结果都是一样的,因此可以用记忆化搜索来优化:

        如果一个状态(递归入参)是第一次遇到,那么可以在返回前,把状态及其结果记到一个 memo 数组中。
        如果一个状态不是第一次遇到(memo 中保存的结果不等于 memo 的初始值),那么可以直接返回 memo 中保存的结果。
        注意:memo 数组的初始值一定不能等于要记忆化的值!例如初始值设置为 0,并且要记忆化的 dfs ( i ) 也等于 0,那就没法判断 0 到底表示第一次遇到这个状态,还是表示之前遇到过了,从而导致记忆化失效。一般把初始值设置为 −1

代码:

class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {int n = cost.size();vector<int> memo(n + 1,-1);function<int(int)>dfs = [&](int i)->int{if(i <= 1) return 0;int& res = memo[i];if(res != -1)   return memo[i];return res = min(cost[i - 1] + dfs(i - 1),cost[i - 2] + dfs(i - 2));};return dfs(n);}
};

算法3:1:1 翻译成递推

我们可以去掉递归中的「递」,只保留「归」的部分,即自底向上计算。

具体来说,dp [ i ] 的定义和 dfs ( i ) 的定义是一样的,都表示从 0 1 爬到 i 的最小花费。

相应的递推式(状态转移方程)也和 dfs 一样:dp [ i ] = min ( dp [ i − 1 ] + cost [ i − 1 ] , dp [ i − 2 ] + cost [ i − 2 ] )
相当于之前是用递归去计算每个状态,现在是枚举并计算每个状态。

初始值 dp [ 0 ] = 0, dp [ 1 ] = 0 ,翻译自递归边界 dfs ( 0 ) = 0 , dfs ( 1 ) = 0 

答案为 dp [ n ] ,翻译自递归入口 dfs ( n ) 

代码:

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

算法4:空间优化

        观察状态转移方程,发现一旦算出 dp [ i ] ,那么 dp [ i − 2 ] 及其左边的状态就永远不会用到了。

        这意味着每次循环,只需要知道「上一个状态」和「上上一个状态」的 f 值是多少,分别记作dp1​ 和 dp0​ 。它俩的初始值均为 0,对应着 dp [ 1 ]  dp [  0 ] 

        每次循环,计算出新的状态 newdp = min ( dp1 +cost [ i − 1 ] , dp0​ + cost [ i − 2 ] ) ,那么对于下一轮循环来说:「上上一个状态」就是 dp1 ​更新 dp0 = dp1 。「上一个状态」就是 newdp ,更新 dp1​ = newdp 
        最后答案为 dp1 ,因为最后一轮循环算出的 newdp 赋给了 dp1​ 。代码实现时,可以把 i 改成从 1 遍历到 n−1,这样 newdp = min ( dp1​ + cost [ i ] , dp0 + cost [ i − 1 ] ) ,可以简化一点代码。

代码:

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

 

相关文章:

​Leetcode 746. 使用最小花费爬楼梯​ 入门dp C++实现

问题&#xff1a;Leetcode 746. 使用最小花费爬楼梯 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你…...

路由协议常见知识点

路由协议是网络通信的基础&#xff0c;主要负责在网络中传递数据包&#xff0c;并确保它们从源节点传递到目标节点。本文将介绍一些常见的路由协议知识点&#xff0c;包括路由协议的分类、特性、配置与管理以及常见问题。 一、路由协议的分类 距离矢量路由协议&#xff1a; R…...

多模态大语言模型(MLLM)-InstructBlip深度解读

前言 InstructBlip可以理解为Blip2的升级版&#xff0c;重点加强了图文对话的能力。 模型结构和Blip2没差别&#xff0c;主要在数据集收集、数据集配比、指令微调等方面下文章。 创新点 数据集收集&#xff1a; 将26个公开数据集转换为指令微调格式&#xff0c;并将它们归类…...

网页前端开发之Javascript入门篇(7/9):字符串

Javascript字符串 什么是字符串&#xff1f; 答&#xff1a;其概念跟 Python教程 介绍的一样&#xff0c;只是语法上有所变化。 在 Javascript 中&#xff0c;一个字符串变量可以看做是其内置类String的一个实例&#xff08;Javascript会自动包装&#xff09;。 因此它拥有一…...

双登股份再战IPO:数据打架,实控人杨善基千万元股权激励儿子

撰稿|行星 来源|贝多财经 近日&#xff0c;双登集团股份有限公司&#xff08;下称“双登股份”&#xff09;递交招股书&#xff0c;准备在港交所主板上市&#xff0c;中金公司、建银国际、华泰国际为其联席保荐人。 贝多财经了解到&#xff0c;这并非双登股份首次向资本市场…...

4.Python 函数(函数的定义、函数的传入参数、函数的返回值、None 类型、函数说明文档、变量的作用域)

一、函数快速入门 1、函数概述 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现特定功能的代码段 name "Hello World" name_length len(name)print(f"{name} 的长度为 {name_length}") # Hello World 的长度为 11len() 是Python 内置的函…...

【JavaEE】——文件IO

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;认识文件 1&#xff1a;文件的概念 2&#xff1a;文件的结构 3&#xff1a;文件路径…...

Python的pandas库基本操作(数据分析)

一、安装&#xff0c;导入 1、安装 使用包管理器安装&#xff1a; pip3 install pandas 2、导入 import pandas as pd as是为了方便引用起的别名 二、DateFrame 在Pandas库中&#xff0c;DataFrame 是一种非常重要的数据结构&#xff0c;它提供了一种灵活的方式来存储和…...

软件测试(平铺版本)

目录 黑盒测试&#xff1a; 定义: 示例&#xff1a;登录功能的黑盒测试 适合使用黑盒测试的情况 几种常见的黑盒测试方法&#xff1a; 1. 等价类划分&#xff08;Equivalence Partitioning&#xff09; 2. 边界值分析&#xff08;Boundary Value Analysis&#xff09; …...

树控件QTreeWidget

树控件跟表格控件类似&#xff0c;也可以有多列&#xff0c;也可以只有1列&#xff0c;可以有多行&#xff0c;只不过每一行都是一个QTreeWidgetItem&#xff0c;每一行都是一个可以展开的树 常用属性和方法 显示和隐藏标题栏 树控件只有水平标题栏 //获取和设置标题栏的显…...

Python酷库之旅-第三方库Pandas(139)

目录 一、用法精讲 626、pandas.plotting.scatter_matrix方法 626-1、语法 626-2、参数 626-3、功能 626-4、返回值 626-5、说明 626-6、用法 626-6-1、数据准备 626-6-2、代码示例 626-6-3、结果输出 627、pandas.plotting.table方法 627-1、语法 627-2、参数 …...

昇思学习打卡营学习记录:CycleGAN壁画修复

按照提示&#xff0c;运行实训代码 进入实训平台&#xff1a;https://xihe.mindspore.cn/projects 选择“jupyter 在线编辑器” 启动“Ascend开发环境” &#xff1a;Ascend开发环境需要申请&#xff0c;大家可以申请试试看 启动开发环境后&#xff0c;在左边的文件夹中&am…...

南京大学《软件分析》李越, 谭添——1. 导论

导论 主要概念: soundcompletePL领域概述 动手学习 本节无 文章目录 导论1. PL(Programming Language) 程序设计语言1.1 程序设计语言的三大研究方向1.2 与静态分析相关方向的介绍与对比静态程序分析动态软件测试形式化(formal)语义验证(verification) 2. 静态分析:2.1莱斯…...

使用seata管理分布式事务

做应用开发时&#xff0c;要保证数据的一致性我们要对方法添加事务管理&#xff0c;最简单的处理方案是在方法上添加 Transactional 注解或者通过编程方式管理事务。但这种方案只适用于单数据源的关系型数据库&#xff0c;如果项目配置了多个数据源或者多个微服务的rpc调用&…...

浏览器指纹

引言 先看下 官网 给的定义。 WebAssembly (abbreviatedWasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server …...

W外链平台有什么优势?

W外链作为一种短网址服务&#xff0c;具备多项功能和技术优势&#xff0c;适用于多种场景&#xff0c;以下是其主要特点和优势&#xff1a; 短域名与高级设置&#xff1a;W外链提供了非常短的域名&#xff0c;这有助于提高用户体验&#xff0c;使其在社交媒体分享时更加便捷。…...

深入理解Spring Cache:加速应用性能的秘钥

一、什么是Spring Cache&#xff1f; Spring Cache是Spring框架中的一部分&#xff0c;它为应用提供了一种统一的缓存抽象&#xff0c;可以轻松集成各种缓存提供者&#xff08;如Ehcache、Redis、Caffeine等&#xff09;。通过使用Spring Cache&#xff0c;开发者可以在方法上…...

C语言入门基础题(力扣):完成旅途的最少时间(C语言版)

1.题目&#xff1a; 给你一个数组 time &#xff0c;其中 time[i] 表示第 i 辆公交车完成 一趟旅途 所需要花费的时间。 每辆公交车可以 连续 完成多趟旅途&#xff0c;也就是说&#xff0c;一辆公交车当前旅途完成后&#xff0c;可以 立马开始 下一趟旅途。每辆公交车 独立 …...

基于LORA的一主多从监测系统_0.96OLED

关联&#xff1a;0.96OLED hal硬件I2C LORA 在本项目中每个节点都使用oled来显示采集到的数据以及节点状态&#xff0c;OLED使用I2C接口与STM32连接&#xff0c;这个屏幕内部驱动IC为SSD1306&#xff0c;SSD1306作为从机地址为0x78 发送数据&#xff1a;起始…...

C#系统学习路线

分享一个C#程序员的成长学习路线规划&#xff0c;希望能够帮助到想从事C#开发的你。 我一直在想&#xff0c;初学者刚开始学习编程时应该学些什么&#xff1f;学习到什么程度才能找到工作&#xff1f;才能在项目中发现和解决Bug&#xff1f; 我不知道每位初学者在学习编程时是…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...