【LeetCode】动态规划—使用最小花费爬楼梯(附完整Python/C++代码)

news2024/11/15 5:10:34

动态规划—#746. 使用最小花费爬楼梯

  • 前言
  • 题目描述
  • 基本思路
    • 1. 问题定义:
    • 2. 理解问题和递推关系:
    • 3. 解决方法:
    • 4. 进一步优化:
    • 5. 小总结:
  • 代码实现
    • Python3代码实现
    • Python 代码解释
    • C++代码实现
    • C++ 代码解释
  • 总结:

前言

在这个问题中,我们有一个数组 c o s t [ ] cost[] cost[],其中 c o s t [ i ] cost[i] cost[i] 表示从第 i i i 个台阶爬到下一个台阶的费用。你可以从第 0 0 0 个台阶或第 1 1 1 个台阶开始,然后每次可以选择爬 1 1 1 个台阶或 2 2 2 个台阶。题目要求的是:你到达楼顶时花费的最小费用是多少?

你需要计算的是,在爬到楼顶时,花费的最小费用。楼顶位于 c o s t cost cost 数组的末尾之后的一个位置,即爬完最后一个台阶后,你就到达了楼顶。

题目描述

在这里插入图片描述

基本思路

1. 问题定义:

在这个问题中,我们有一个数组 c o s t [ ] cost[] cost[],其中 c o s t [ i ] cost[i] cost[i] 表示从第 i i i 个台阶爬到下一个台阶的费用。你可以从第 0 0 0 个台阶或第 1 1 1 个台阶开始,然后每次可以选择爬 1 1 1 个台阶或 2 2 2 个台阶。题目要求的是:你到达楼顶时花费的最小费用是多少?

你需要计算的是,在爬到楼顶时,花费的最小费用。楼顶位于 c o s t cost cost 数组的末尾之后的一个位置,即爬完最后一个台阶后,你就到达了楼顶。

2. 理解问题和递推关系:

到达楼顶的最小费用可以通过递推计算:

  • 假设 d p [ i ] d p[i] dp[i] 是爬到第 i i i 个台阶的最小花费。
  • 你可以从 i − 1 i-1 i1 或者 i − 2 i-2 i2 台阶爬到第 i i i 个台阶。相应地,爬到第 i i i 台阶的最小花费是前面两阶的最小花费,加上 cost ⁡ [ i ] \operatorname{cost}[i] cost[i]

d p [ i ] = min ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] ) + cost ⁡ [ i ] d p[i]=\min (d p[i-1], d p[i-2])+\operatorname{cost}[i] dp[i]=min(dp[i1],dp[i2])+cost[i]

到达楼顶的情况是你从第 n − 1 n-1 n1 n − 2 n-2 n2 台阶爬上去,而楼顶没有对应的花费。

3. 解决方法:

  1. 初始条件: 你可以从第 θ \theta θ 或第 1 个台阶开始。因此 d p [ θ ] = cost ⁡ [ θ ] , d p [ 1 ] = cost ⁡ [ 1 ] d p[\theta]=\operatorname{cost}[\theta], d p[1]=\operatorname{cost}[1] dp[θ]=cost[θ],dp[1]=cost[1]
  2. 递推公式:对于第 i i i 个台阶, d p [ i ] = min ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] ) + cost ⁡ [ i ] d p[i]=\min (d p[i-1], d p[i-2])+\operatorname{cost}[i] dp[i]=min(dp[i1],dp[i2])+cost[i]
  3. 目标: 计算出 d p [ n − 1 ] d p[n-1] dp[n1] d p [ n − 2 ] d p[n-2] dp[n2] 的最小值,因为到达楼顶时你可能是从这两个台阶之一爬上去的。

4. 进一步优化:

我们注意到在每一步递推时, d p [ i ] d p[i] dp[i] 只依赖于 d p [ i − 1 ] d p[i-1] dp[i1] d p [ i − 2 ] d p[i-2] dp[i2] ,因此可以用两个变量代替整个 dp[] 数组,减少空间复杂度。

  • 时间复杂度: O ( n ) O(n) O(n) ,因为我们只需要遍历一次数组。
  • 空间复杂度: O ( 1 ) O(1) O(1) ,只需要常量空间保存前两阶的最小费用。

5. 小总结:

  • 本质是一个动态规划问题,通过递推公式 d p [ i ] = min ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] ) + cost ⁡ [ i ] d p[i]=\min (d p[i-1], d p[i-2])+\operatorname{cost}[i] dp[i]=min(dp[i1],dp[i2])+cost[i] 来逐步计算。
  • 我们可以通过优化将空间复杂度从 O ( n ) O(n) O(n) 降低到 O ( 1 ) O(1) O(1)
  • 目标是计算出到达楼顶的最小花费,最后从 n − 1 n-1 n1 n − 2 n-2 n2 台阶上去。

以上就是使用最小花费爬楼梯问题的基本思路。

代码实现

Python3代码实现

class Solution:
    def minCostClimbingStairs(self, cost: list[int]) -> int:
        # 如果台阶数少于 2 直接返回最低的花费
        if len(cost) == 0:
            return 0
        elif len(cost) == 1:
            return cost[0]
        
        # 初始化前两个台阶的最小花费
        prev2 = cost[0]
        prev1 = cost[1]
        
        # 从第3个台阶开始(即索引2),逐步计算每个台阶的最小花费
        for i in range(2, len(cost)):
            current = min(prev1, prev2) + cost[i]
            prev2 = prev1  # 更新前一个台阶的花费
            prev1 = current  # 更新当前台阶的花费
        
        # 到达楼顶的最小花费可以从倒数第一或倒数第二个台阶上去
        return min(prev1, prev2)

Python 代码解释

  1. Base Case: 如果 c o s t [ ] cost[] cost[] 长度为 0 或 1 ,直接返回最小花费。
  2. 动态规划:用 prev2 和 prev1 存储爬到前两个台阶的最小花費,并依次更新。
  3. 最终结果:返回最后两个台阶中较小的花费。

C++代码实现

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        // 如果台阶数少于2,直接返回最低的花费
        if (cost.size() == 0) return 0;
        if (cost.size() == 1) return cost[0];
        
        // 初始化前两个台阶的最小花费
        int prev2 = cost[0];
        int prev1 = cost[1];
        
        // 从第3个台阶开始(即索引2),逐步计算每个台阶的最小花费
        for (int i = 2; i < cost.size(); ++i) {
            int current = min(prev1, prev2) + cost[i];
            prev2 = prev1;  // 更新前一个台阶的花费
            prev1 = current;  // 更新当前台阶的花费
        }
        
        // 到达楼顶的最小花费可以从倒数第一或倒数第二个台阶上去
        return min(prev1, prev2);
    }
};


C++ 代码解释

  1. Base Case: 如果 c o s t [ ] cost[] cost[] 长度为 0 或 1 ,直接返回最小花费。
  2. 动态规划:用两个变量 prev2 和 prev1 来存储前两个台阶的最小花费,通过循环不断更新。
  3. 最终结果:返回最后两个台阶的最小花费。

总结:

  • 该问题的核心是动态规划,通过递推公式计算每个台阶的最小花费。
  • 为了优化空间复杂度,我们只使用两个变量来存储前两阶的最小花费。
  • 通过 Python 和 C++ 的实现,可以有效计算出爬到楼顶的最小费用。

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

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

相关文章

单细胞SCENIC简单可视化分析学习和整理

SCENIC教程中给出三个方法进行下游的可视化分析&#xff0c;分别可以选择网页(SCope)平台&#xff0c;R或者python进行分析。 1、网页版&#xff1a;https://scope.aertslab.org/ 把数据从左侧工具栏处上传之后就可以个性化分析了~ 2、R和Python就殊途同归啦~ 笔者基于githu…

linux/CentOS 开机启动程序

前言 TencentOS Server 3.1 (TK4)适用于自己编写启动脚本的情况 编写启动脚本 比如启动tomcat&#xff0c;kaijiqidong_tomcat.sh #!/bin/bashecho "kaijiqidong_tomcat on date ." >> kaijiqidong_tomcat.log 2>&1cd /x/xx/xxx sh /x/tomcat/bin/s…

老照片修复软件有哪些?6个工具轻松搞定

在回忆的长廊中&#xff0c;老照片承载着岁月的痕迹和珍贵的记忆。 然而&#xff0c;时间的流逝往往让这些宝贵的瞬间变得模糊不清。幸运的是&#xff0c;现代科技赋予了我们修复这些老照片的能力。 面对市场上众多的老照片自动修复软件&#xff0c;选择一个合适的工具变得尤…

Apache APISIX学习(1):介绍、docker启动

一、介绍 Apache APISIX 是一个动态、实时、高性能的 API 网关&#xff0c; 提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。你可以把 Apache APISIX 当做流量入口&#xff0c;来处理所有的业务数据&#xff0c;包括动态路由、动态上游…

得物自建 Redis 无人值守资源均衡调度设计与实现

目录&#xff1a; 一、为什么要做资源均衡调度 二、为什么要做自动化资源均衡调度 三、如何合理选择迁移节点 四、如何保障迁移过程中可靠性1. 添加从节点2. 检查同步数据正常3. 执行主从切换4. 检查主从切换正常5. 删除待迁移节点6. 消息通知 五、迁移任务管理展示 六、总结 …

户用光伏项目难管理,到底该怎么办?

一、鹧鸪云光伏业务管理软件&#xff1a;一站式管理利器 鹧鸪云光伏业务管理软件&#xff0c;作为一款专为光伏行业量身定制的智能化管理工具&#xff0c;集成了项目管理、运维管理、数据分析、用户服务等多功能模块于一体&#xff0c;旨在通过数字化手段&#xff0c;实现户用…

Nature Genetics|三代测序微量建库技术:媲美WGBS的直接甲基化检测

DNA修饰和甲基化是理解基因调控机制的关键。以往&#xff0c;我们的经验表明&#xff0c;使用三代测序从未经扩增的长DNA模板中同时读取序列信息和碱基修饰&#xff0c;需要投入大量的DNA样本来构建文库。 今天&#xff0c;小编带大家看一篇2024年发表于《Nature Genetics》的…

【MAUI】FlexLayout

文章目录 概述属性方向和对齐方式DirectionWrapJustifyContentAlignItemsAlignContent 圣杯布局来源 概述 FlexLayout弹性布局&#xff0c;和前端的Flex弹性布局&#xff0c;几乎一样。FlexLayout是容器&#xff0c;可以定义Direction/主轴方向、Wrap/子元素在主轴方向上是否换…

Vue使用Vue Router路由:开发单页应用

1、路由基础 在单页 Web 应用中&#xff0c;整个项目只有一个 HTML 文件&#xff0c;不同视图&#xff08;组件的模块&#xff09;的内容都是在同一个页面中渲染的。当用户切换页面时&#xff0c;页面之前的跳转都是在浏览器端完成的&#xff0c;这时就需要使用前端路由。 路…

蒙古语有方言差异吗?

蒙古语存在方言差异&#xff0c;主要分为西部方言和东部方言两大类。西部方言&#xff0c;即蒙古方言或喀尔喀方言&#xff0c;主要在蒙古国使用&#xff0c;是该国的官方语言。东部方言&#xff0c;又称布里亚特方言或巴尔虎-布里亚特方言&#xff0c;主要在中国内蒙古自治区和…

deepin桌面版连接windows远程桌面

在Linux系统中&#xff0c;要登录到Windows系统&#xff0c;通常可以使用远程桌面协议(RDP)。你需要在Linux系统上安装RDP客户端。 使用如下命令安装rdp协议&#xff1a; sudo apt-get install xrdp 安装成功后&#xff0c;启动rdp服务。 sudo systemctl start xrdp 有了r…

vscode缩进 和自动格式化

如下图&#xff0c;缩进太大了。 检查2个地方 prettierrc.cjs文件。此处决定缩进几个tab vscode 的设置。 保存的时候 格式化。

Apache Druid命令执行(CVE-2021-25646)

漏洞详情&#xff1a; Apache Druid 是用Java编写的面向列的开源分布式数据存储系统&#xff0c;旨在快速获取大量事件数据&#xff0c;并在数据之上提供低延迟查询。 Apache Druid含有能够执行嵌入在各种类型请求中由用户提供的JavaScript代码功能。此功能适用于高度信任环境…

Java_Day04学习

类继承实例 package com.dx.test03; public class extendsTest {public static void main(String args[]) {// 实例化一个Cat对象&#xff0c;设置属性name和age&#xff0c;调用voice()和eat()方法&#xff0c;再打印出名字和年龄信息/********* begin *********/Cat cat ne…

李飞飞创业公司World Labs:引领AI新方向的“大世界模型”

引言 随着人工智能的不断进步&#xff0c;AI领域涌现了许多新兴技术和研究方向。在这其中&#xff0c;李飞飞创办的World Labs凭借其独特的“空间智能”和“大世界模型”&#xff08;Large World Model, LWM&#xff09;理念&#xff0c;迅速成为焦点。尤其是在获得了2.3亿美元…

python 斑马打印模板

打印代码逻辑如下&#xff1b; 包括样式、表格 import win32printdef print_zpl_from_usb_printer(printer_name, zpl_content):# 打开打印机hPrinter win32print.OpenPrinter(printer_name)if hPrinter is None:print(f"Failed to open printer: {printer_name}")…

淘宝商品评论数据获取API接口响应参数列表展示(可测key)

item_review-获得淘宝商品评论 在电商领域&#xff0c;商品评论数据是商家和消费者都极为关注的重要信息。通过这些数据&#xff0c;商家可以了解产品的市场反馈&#xff0c;优化产品和服务&#xff1b;而消费者则可以参考其他用户的评价&#xff0c;做出更明智的购买决策。然…

Vulkan 学习(9)---- vkSuraceKHR 创建

目录 OverView创建窗口表面参考代码 OverView Vulkan 是一个平台无关的图形API&#xff0c;这意味着它不能直接与特定的窗口系统(Windows&#xff0c;linux 和 macOS 的窗口系统)进行交互 为了解决这个问题&#xff0c;Vulkan 引入了窗口系统集成(Window System Intergration …

Flutter为Android添加签名并打包

前言 我们需要将App进行数字签名才能发布到商店里。在这里就具体描述一下如果给App添加签名 为App签名 创建一个用户上传的秘钥库 如果你已经有一个秘钥库了&#xff0c;可以直接跳到下一步&#xff0c;如果没有则按照下面的指令创建一个 keytool 可能不在我们的系统路径中…

Vxe UI vue vxe-table 实现自适应列宽,根据内容自适应列的宽度

Vxe UI vue vxe-table 实现自适应列宽&#xff0c;根据内容自适应列的宽度 之前老版本是通过计算字符数量&#xff0c;然后给动态给每一列设置宽度&#xff0c;不仅麻烦&#xff0c;还不好复用。 看了 API 发现 v4.7 和 v3.9 版本已经直接就能支持了&#xff0c;只需加上 widt…