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

代码随想录算法训练营第38天|● 理论基础 ● 509. 斐波那契数● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

动态规划理论基础

动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。

所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,


动态规划做题步骤

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

动态规划做题debug

  1. 找问题的最好方式就是把dp数组打印出来
  2. 做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果

斐波那契数

509. 斐波那契数 - 力扣(LeetCode)

本题为动态规划入门题,根据题目进行模拟即可

1.确定dp数组以及下标的含义

dp[i]的定义为:第i个数的斐波那契数值是dp[i]

2.确定递推公式

为什么这是一道非常简单的入门题目呢?

因为题目已经把递推公式直接给我们了:状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];

3.dp数组如何初始化

题目中把如何初始化也直接给我们了,如下:

arr[0]=0;

arr[1]=1;

4.确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的

class Solution {public int fib(int n) {if (n <= 1) {return n;}int[] arr = new int[2];arr[0] = 0;arr[1] = 1;for (int i = 2; i <= n; i++) {int sum = arr[0] + arr[1];arr[0] = arr[1];arr[1] = sum;}return arr[1];}
}

爬楼梯

70. 爬楼梯 - 力扣(LeetCode)

     1.确定dp数组(dp table)以及下标的含义

          到达第i 层有dp[i]种方法

      2.确定递推公式

           dp[i]=dp[i-1]+dp[i-2]

      3.dp数组如何初始化

           dp[1]=1;  

          dp[2]=1;

     4.确定遍历顺序

         从前向后遍历

代码:

class Solution {public int climbStairs(int n) {if(n<=2){return n;}int[] arr = new int[2];arr[0] = 1;arr[1] = 2;for (int i = 3; i <= n; i++) {int sum = arr[0] + arr[1];arr[0] = arr[1];arr[1] = sum;}return arr[1];}
}

使用最小花费爬楼梯 

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

1.确定dp数组以及下标的含义

    dp[i]的定义:到达第i台阶所花费的最少体力为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] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);

3.dp数组初始化

由题目可以知道你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。所以从0或1开始不需要花钱

dp[0]=0;dp[1]=0;

4.遍历顺序

从前向后

class Solution {public int minCostClimbingStairs(int[] cost) {int[] dp = new int[cost.length + 1];dp[0] = 0;dp[1] = 0;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];}
}

相关文章:

  • Linux:文件描述符
  • ai写诗词,三款软件助你妙笔生花!
  • Cesium4Unreal - # 009 直接加载显示Shapefile
  • 返回给前端数据的封装
  • 【Spine学习13】之 制作受击动画思路总结(叠加颜色特效发光效果)
  • Go 基础丨字符串 string
  • 【已解决】better-scroll在PC端如何开启鼠标滚动以及如何始终显示滚动条
  • Vim基础操作:常用命令、安装插件、在VS Code中使用Vim及解决Vim编辑键盘错乱
  • 北方高温来袭!动力煤却不涨反跌的原因分析
  • 分支结构相关
  • JEnv-for-Windows 详细使用
  • 关于ReactV18的页面跳转传参和接收
  • 【干货分享】25地学考研推免夏令营汇总表
  • SpringBoot 多种优雅的线程池配置与使用(异步执行函数,反射机制,动态识别参数,有返回值)
  • 2024年6月20日 (周四) 叶子游戏新闻
  • Angular6错误 Service: No provider for Renderer2
  • CODING 缺陷管理功能正式开始公测
  • Javascript弹出层-初探
  • Laravel5.4 Queues队列学习
  • leetcode98. Validate Binary Search Tree
  • node.js
  • 关于extract.autodesk.io的一些说明
  • 聊一聊前端的监控
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 一道闭包题引发的思考
  • const的用法,特别是用在函数前面与后面的区别
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • ‌JavaScript 数据类型转换
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (LeetCode C++)盛最多水的容器
  • (笔试题)分解质因式
  • (多级缓存)缓存同步
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (三十五)大数据实战——Superset可视化平台搭建
  • (算法)大数的进制转换
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)c++ std::pair 与 std::make
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net 受管制代码
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .Net7 环境安装配置
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)
  • .net快速开发框架源码分享
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • .NET应用UI框架DevExpress XAF v24.1 - 可用性进一步增强
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • ??如何把JavaScript脚本中的参数传到java代码段中