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

一文搞懂从爬楼梯到最小花费(力扣70,746)


文章目录

  • 题目
  • 前知
    • 动态规划简介
    • 动态规划模版
  • 爬楼梯
    • 一、思路
    • 二、解题方法
    • 三、Code
  • 使用最小花费爬楼梯
    • 一、思路
    • 二、解题方法
    • 三、Code
  • 总结


在计算机科学中,动态规划是一种强大的算法范例,用于解决多种优化问题。本文将介绍动态规划的核心思想,并通过两个经典的力扣题目展示其应用:爬楼梯(LeetCode 70)和使用最小花费爬楼梯(LeetCode 746)

题目

Problem: 70. 爬楼梯
Problem: 746. 使用最小花费爬楼梯

爬楼梯
假设你正在爬楼梯。需要 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 阶

使用最小花费爬楼梯
给你一个整数数组 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 。

前知

动态规划简介

动态规划算法(Dynamic Programming)是一种解决多阶段决策过程最优化问题的方法。它将问题分解为相互重叠的子问题,并通过解决子问题来解决整个问题。这种方法通常用于具有重叠子问题和最优子结构性质的问题。

动态规划的基本思想是将原问题分解为相互重叠的子问题,并在解决这些子问题时进行存储,以避免重复计算。通过这种方式,可以大大减少计算量,提高算法效率。动态规划算法通常涉及两个关键步骤:定义状态和状态转移方程。

  • 定义状态: 确定问题中的状态变量,并定义状态之间的关系。状态变量描述问题的当前情况,是动态规划算法的关键。

  • 状态转移方程: 建立状态之间的转移关系,描述如何从一个状态转移到另一个状态。这个方程描述了问题的最优子结构,是动态规划算法的核心。

动态规划算法通常用于解决一些优化问题,例如最长公共子序列、最短路径、背包问题等。在实际应用中,动态规划常常能够以较高效率解决一些复杂的问题,但需要注意的是,有时需要权衡时间和空间复杂度。

与贪心算法的区别:

  1. 最优子结构性质:
  • 动态规划: 动态规划问题具有最优子结构性质,即问题的最优解可以通过子问题的最优解来构造。在解决动态规划问题时,通常需要考虑所有可能的子问题,并选择其中最优的解进行组合。
  • 贪心算法: 贪心算法也寻求问题的最优解,但它通常通过在每个步骤中选择当前状态下的局部最优解来构造全局最优解。贪心算法没有最优子结构性质,它只关注当前状态下的最优选择,而不考虑后续状态的影响。
  1. 状态的存储与重复计算:
  • 动态规划: 动态规划算法通常利用存储来避免重复计算子问题,因此可以在解决问题时节省计算时间。通过记忆化搜索或者建立动态规划表格,可以将子问题的解存储起来,以便后续使用。
  • 贪心算法: 贪心算法通常不需要存储中间状态或者解决方案,因为它只关注当前状态下的最优选择。这意味着贪心算法通常需要更少的存储空间。
  1. 适用范围:
  • 动态规划: 动态规划通常适用于具有重叠子问题和最优子结构性质的问题,例如最长公共子序列、最短路径、背包问题等。这些问题通常需要考虑多阶段决策过程,而动态规划能够有效地处理这种情况。
  • 贪心算法: 贪心算法通常适用于具有贪心选择性质的问题,即每个步骤都可以做出局部最优选择,并且这些局部最优选择能够导致全局最优解。贪心算法通常更简单、更高效,但只适用于部分问题,因为它没有考虑全局的影响。

动态规划模版

与之前讲的递归三部曲还有回溯三部曲都是类似的

动规五部曲:在这里面dp数组是非常重要的,一定要搞清楚dp数组的含义究竟是什么含义

在这里插入图片描述

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

爬楼梯

一、思路

第二层可以由第一层爬一个楼梯上来或者由第零层爬两个楼梯上来,二层以上都可以这样推出来,于是只要求出第零层和第一层的上楼方法就可以了

二、解题方法

动规五部曲

  1. 确定dp数组及下标i的含义:到达i层有dp[i]种不同的方法

  2. 确定递推公式:dp[i] = dp[i-1] + dp[i-2],第2层由第零层dp[0]或第一层dp[1]下一步得出,在推导dp[i]的时候,一定要时刻想着dp[i]的定义,否则容易跑偏。这体现出确定dp数组以及下标的含义的重要性!

  3. dp数组如何初始化:两层之后都可以由dp[0]dp[1]得出

  4. 确定遍历顺序:从递推公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,遍历顺序一定是从前向后遍历的

  5. 举例推导dp数组:当n=5时dp数组应该是这样的:

在这里插入图片描述

三、Code

class Solution {public int climbStairs(int n) {int[] dp =new int[n+1];dp[0] = 1;dp[1] = 1;for(int i=2;i<=n;i++){dp[i] = dp[i-1] + dp[i-2];}return dp[n];}
}

使用最小花费爬楼梯

一、思路

此题在上一题的基础上进行了爬楼梯需要耗费cost数组所需的体力,才能够向上爬,而站在起点0或起点1是不需要耗费体力的

二、解题方法

动规五部曲

  1. 确定dp数组及下标i的含义:到达第i个台阶所需要的最小花费dp[i]

  2. 确定递推公式:因为可以一次跳一个或两个台阶,所以dp[i]有两种方式得到,由dp[i-1]加上离开这层所需花费的cost[i-1]或者由dp[i-2]加上离开这层所需花费的cost[i-2],从两种情况中选最小的那个,所以要用Math.min(...,...)对两个结果进行比较得到dp[i]

  3. dp数组如何初始化:只需要初始化dp[0]dp[1]即可,其它dp都可以由这两个推出来,题目说可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯,所以dp[0]dp[1]都为0,不需要花费

  4. 确定遍历顺序:从前到后遍历cost数组

  5. 举例推导dp数组:用题目给的实例1进行举例,cost = [10,15,20],可以推出dp[0]=0,dp[1]=0,dp[2]=dp[0]+cost[0]=10,dp[3]=dp[1]+cost[1]=15。最后输出的确实是dp[3]=15。如下图所示:

image.png

三、Code

class Solution {public int minCostClimbingStairs(int[] cost) {// 到达第i层的最小花费dp[i]int[] dp = new int[cost.length + 1];dp[0] = 0;dp[1] = 0;// 最上面还有一层,台阶cost数组有三个,但是有四层楼梯for (int i = 2; i <= cost.length; i++) {dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);}return dp[cost.length];}
}

总结

通过以上两个力扣题目的介绍,我们了解了动态规划算法在解决爬楼梯问题中的应用。动态规划算法不仅能够解决这类问题,还可以应用于更广泛的优化问题。希望本文能够帮助读者更好地理解和应用动态规划算法在爬楼梯问题中的使用,如果有任何疑问或者建议,欢迎留言讨论🌹

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 语义分割交互式智能标注工具 | 澳鹏数据标注平台
  • LangChain - OpenGPTs
  • GO - 泛型编程
  • 深入浅出 -- 系统架构之负载均衡Nginx实现高可用
  • 面试算法-148-轮转数组
  • Chatgpt掘金之旅—有爱AI商业实战篇|内容策展业务|(八)
  • Springboot中JSCH的使用
  • RabbitMQ面经 手敲浓缩版
  • iOS 开发中上传 IPA 文件的方法(无需 Mac 电脑
  • 2014最新AI智能系统ChatGPT网站源码+Midjourney绘画网站源码+搭建部署教程文档
  • 【嵌入式开发 Linux 常用命令系列 4.3 -- git add 不 add untracked file】
  • Zookeeper脑裂解决方案
  • 面试题:MySQL 优化篇
  • 达梦备份与恢复
  • vue3中封装table表格
  • [PHP内核探索]PHP中的哈希表
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 【5+】跨webview多页面 触发事件(二)
  • 【mysql】环境安装、服务启动、密码设置
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Linux后台研发超实用命令总结
  • linux学习笔记
  • node.js
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Python学习之路13-记分
  • Redis的resp协议
  • SpringCloud集成分布式事务LCN (一)
  • SwizzleMethod 黑魔法
  • vue-router的history模式发布配置
  • 代理模式
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 开源SQL-on-Hadoop系统一览
  • 前端代码风格自动化系列(二)之Commitlint
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 移动端 h5开发相关内容总结(三)
  • 找一份好的前端工作,起点很重要
  • 正则表达式
  • 自动记录MySQL慢查询快照脚本
  • 回归生活:清理微信公众号
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (12)目标检测_SSD基于pytorch搭建代码
  • (c语言)strcpy函数用法
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (分布式缓存)Redis哨兵
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (四)opengl函数加载和错误处理
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (杂交版)植物大战僵尸
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • .Net 基于MiniExcel的导入功能接口示例