代码随想录-刷题第三十九天

动态规划理论基础

动态规划的题目由重叠子问题构成,每一个状态一定是由上一个状态推导出来的。这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。

动态规划五步曲

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

动态规划里面递推公式十分重要,但是确定dp数组,初始化,遍历顺序也同样十分重要,一定要严格按照这五步进行,将每一步的思路理清。

做动态规划的题目遇到问题时,最好的方式就是打印出dp数组,看是否和自己推理一致。


509. 斐波那契数

题目链接:509. 斐波那契数

思路:动态规划五步曲:

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

  2. 递推公式:dp[i] = dp[i - 1] + dp[i - 2]

  3. 初始化:dp[0] = 0, dp[1] = 1

  4. 从递推公式可以看出,一定是从前向后遍历的。

  5. 举例看是否可行,当N为10的时候,dp数组应该是如下的数列:

    0 1 1 2 3 5 8 13 21 34 55

    如果代码写出来,发现结果不对,就把dp数组打印出来看看与推导的数列是否一致。

class Solution {public int fib(int n) {if (n == 0) return 0;if (n == 1) return 1;             int[] dp = new int[n + 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];}
}

可以发现,只需要维护两个数值,不需要记录整个序列。代码如下:

class Solution {public int fib(int n) { // 动态规划if (n <= 1) return n;int dp0 = 0;int dp1 = 1;for (int i = 2; i <= n; i++) {int sum = dp1 + dp0;dp0 = dp1;dp1 = sum;}return dp1;}
}

70. 爬楼梯

题目链接:70. 爬楼梯

思路:动态规划五步曲

  1. dp[i]: 爬到第i层楼梯,有dp[i]种方法

  2. 递推公式:dp[i] = dp[i - 1] + dp[i - 2]

    从dp[i]的定义可以看出,dp[i] 可以有两个方向推出来。

    首先是dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,那么再一步跳一个台阶不就是dp[i]了么。

    还有就是dp[i - 2],上i-2层楼梯,有dp[i - 2]种方法,那么再一步跳两个台阶不就是dp[i]了么。

    那么dp[i]就是 dp[i - 1]与dp[i - 2]之和!所以dp[i] = dp[i - 1] + dp[i - 2] 。

    在推导dp[i]的时候,一定要时刻想着dp[i]的定义,否则容易跑偏。

  3. 初始化:dp[1] = 1, dp[2] = 2

    题目提示:1 <= n <= 45,所以本题不用考虑dp[0]的初始化!

  4. 从递推公式可以看出是从前向后遍历。

  5. 举例看是否可行

class Solution {public int climbStairs(int n) {if (n == 1) return 1;// 1、确定dp数组及下标含义// dp[i]代表爬到第i层楼梯,有dp[i]种方法int[] dp = new int[n + 1];// 2、确定递推函数// dp[i] = dp[i - 1] + dp[i - 2]// 3、确定初始化dp[1] = 1;dp[2] = 2;// 4、确定遍历顺序for (int i = 3; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}

本题与斐波那契数相同,可以将空间复杂度从O(n)降为O(1)。


746. 使用最小花费爬楼梯

题目链接:746. 使用最小花费爬楼梯

思路:动态规划五步曲

  1. dp[i]的定义:到达第i台阶所花费的最少体力为dp[i]。

    题目中说 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯” 也就是相当于 跳到 下标 0 或者 下标 1 是不花费体力的, 从 下标 0 下标1 开始跳就要花费体力了。

  2. 递推公式:dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])

    可以有两个途径得到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]跳呢?一定是选最小的!

  3. 初始化:dp[0] = 0, dp[1] = 0。我们认为第一步无需支付费用,所以到第一个台阶和到第二个台阶都是0。

  4. 遍历顺序为从前到后

  5. 举例推导dp数组

    拿cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] ,来模拟一下dp数组的状态变化

    img

    如果代码写出来有问题,就把dp数组打印出来,看看和如上推导的是否一致。

class Solution {public int minCostClimbingStairs(int[] cost) {int len = cost.length;int[] dp = new int[len + 1];// 每次最多走两步,前两个台阶无需支付费用dp[0] = 0;dp[1] = 0;// 计算到达每一层台阶的最小费用for (int i = 2; i <= len; i++) {dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);}return dp[len];}
}

还可以优化空间复杂度,因为dp[i]就是由前两位推出来的,那么也不用dp数组了

class Solution {public int minCostClimbingStairs(int[] cost) {int len = cost.length;// 每次最多走两步,前两个台阶无需支付费用int dp0 = 0;int dp1 = 0;// 计算到达每一层台阶的最小费用for (int i = 2; i <= len; i++) {int dp_i = Math.min(dp1 + cost[i - 1], dp0 + cost[i - 2]);dp0 = dp1;dp1 = dp_i;}return dp1;}
}

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

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

相关文章

Matlab:非线性规划

1、语法&#xff1a; xfmincon(fun,x0,A,b) xfmincon(fun,x0,A,b,Aeq,beq) xfmincon(fun,x0,A,b,Aeq,beq,lb,ub) xfmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon) xfmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options) xfmincon(problem) [x,fval]fmincon(___) [x,fval,exitflag,…

vue前端学习笔记

filter() 方法创建给定数组一部分的浅拷贝&#xff0c;其包含通过所提供函数实现的测试的所有元素。 const words [active, sunlight, self-confident, clever, health];const result words.filter((word) > word.length 6);console.log(result);结果如下&#xff1a; &…

Vue指令详解

聚沙成塔每天进步一点点 本文内容 ⭐ 专栏简介1. `v-bind`2. `v-model`3. `v-if` / `v-else-if` / `v-else`4. `v-for`5. `v-on`6. `v-show`7. `v-pre`8. `v-cloak`⭐ 写在最后⭐ 专栏简介 Vue学习之旅的奇妙世界 欢迎大家来到 Vue 技能树参考资料专栏!创建这个专栏的初衷

边缘检测——PidiNet网络训练自己数据集并优化推理测试(详细图文教程)

PiDiNet 是一种用于边缘检测的算法&#xff0c;它提出了一种简单、轻量级但有效的架构。PiDiNet 采用了新 颖的像素差卷积&#xff0c;将传统的边缘检测算子集成到现代 CNN 中流行的卷积运算中&#xff0c;以增强任务性能。 在 BSDS500、NYUD 和 Multicue 上进行了大量的实验…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数(C#)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用UserSet功能保存和载入相机的各类参数&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机NEOAPISDK中UserSet的技术背景代码案例分享第一步&#xff1a;保存相机当前参数设置UserSet_Save第二步&#xff1a;载入已经保…

go 语言程序设计第1章--入门

1.1 hello, world helloworld.go package mainimport "fmt"func main() {fmt.Println("Hello, World") }执行 go run helloworld.go 运行程序。 构建和执行. go build helloworld.go ./helloworld1.2 命令行参数 变量 os.Args 是一个字符串 slice. …

1527. 患某种疾病的患者

1527. 患某种疾病的患者 患者信息表&#xff1a; Patients --------------------- | Column Name | Type | --------------------- | patient_id | int | | patient_name | varchar | | conditions | varchar | --------------------- 在 SQL 中&#xff0c;patient_id &…

高并发系统常见问题及解决方案(Java)

在 Java Web 应用中,高并发环境会带来一系列的挑战,这些挑战可能会影响应用的性能、稳定性和可用性。下面是一些常见的问题以及相应的解决方案: 1. 线程资源竞争 问题: 当多个线程尝试同时访问同一资源时,可能会导致竞争条件,进而影响数据的完整性。 解决方案: 使用同步…

小米路由器2(R2D) 安装 MIXBOX

1. 先刷开发版 ROM http://www1.miwifi.com/miwifi_download.html 进入上述网页&#xff0c;找到 R2D 点击下载 开发版 ROM 教程 看 下载按钮上边的 “刷机教程” 刷机教程 2. 开启SSH工具 登录自己的小米账号后&#xff0c;里面会显示出 自己的 root密码&#xff1b; 默认…

『JavaScript』JavaScript事件类型详解:全面解析各类用户交互行为

&#x1f4e3;读完这篇文章里你能收获到 理解事件驱动编程的基本概念和工作原理掌握JavaScript中常见的事件类型及其应用场合学习如何使用DOM API添加和移除事件监听器探讨事件冒泡、事件捕获和事件委托等高级事件处理技术 文章目录 一、事件处理程序1. HTML事件处理HTML事件处…

Springboot拦截器及统一异常处理

文章目录 一、Java中异常相关概念1、异常类2、异常处理方法3、注意事项4、自定义异常 二、配置全局异常处理1、统一返回体定义2、定义异常处理实现类3、全局异常处理类 三、Springboot拦截器1、定义拦截器2、注册拦截器 四、验证效果 一、Java中异常相关概念 1、异常类 Throw…

Armpro脱壳软件搭建教程附源代码

PHP8.0版本&#xff0c;数据库8.0版本 1.配置注册机文件&#xff0c;打开将arm.zip/res目录下&#xff0c;mt管理器搜索将其全部修改为你自己的域名或者是服务器IP 2.然后建立数据库 数据库账号arm 数据库用户名arm 数据库密码EsZfXY4tD3h2NNA4 3.导入数据库 4.配置Redi…

Vue.js项目部署至Linux服务器的详细步骤

引言 在现代Web开发中&#xff0c;Vue.js作为一款流行的前端框架&#xff0c;为开发者提供了灵活且高效的工具。然而&#xff0c;在将Vue.js项目成功部署到Linux服务器上&#xff0c;可能需要一些额外的步骤和注意事项。本文将深入介绍在Linux服务器上部署Vue.js项目的详细步骤…

[每周一更]-(第44期):GIT版本控制之忽略文件

基础概念 在 Git 中&#xff0c;可以通过 .gitignore 文件来指定不需要纳入版本控制的文件或文件夹&#xff0c;这些被忽略的文件或文件夹不会被提交到仓库中。 在项目根目录下创建一个名为 .gitignore 的文件&#xff0c;并在其中列出需要忽略的文件或文件夹。一些常见的示例…

【经验模态分解】5.结合EMD与最小二乘法的信号趋势项的提取方法

利用 EMD 将信号分解为一系列 固有模态函数IMF&#xff0c;根据 振动信号过零点特性 对属于趋势项的 IMF 分量进行判别&#xff0c;并对判别为趋势项的 IMF 分量进一步利用 最小二乘法 进行趋势项拟合&#xff0c;将拟合结果求和作为最终趋势项。数值模拟试验和实测数据处理结果…

SASS循环

<template><div><button class"btn type-1">默认按钮</button><button class"type-2">主要按钮</button><button class"type-3">成功按钮</button><button class"type-4">信息…

EMQTT消息订阅的几种方式

1、普通订阅 生产者 topic&#xff1a; demo 订阅者topic&#xff1a;demo 一个生产者&#xff0c;多个订阅者&#xff0c;每个消息都会被每个订阅者消费 2、分组订阅 &#xff08;1&#xff09;queue模式&#xff1a;特殊的分组&#xff0c;也就是一个分组&#xff0c;里面是…

安卓逆向笔记之AndroidManifest.xml篇

AndroidManifest.xml篇 AndroidManifest.xml是Android应用程序中最重要的文件之一&#xff0c;它包含了应用程序的基本信息&#xff0c;如应用程序的名称、图标、版本号、权限、组件&#xff08;Activity、Service、BroadcastReceiver、Content Provider&#xff09;等等。在应…

企业数据可视化-亿发数据化管理平台提供商,实现一站式数字化运营

近些年来&#xff0c;国内企业数据化管理升级进程持续加速&#xff0c;以物联网建设、人工智能、大数据和5G网络等新技术的发展&#xff0c;推动了数字经济的蓬勃发展&#xff0c;成为维持经济持续稳定增长的重要引擎。如今许多国内中小型企业纷纷摒弃传统管理模式&#xff0c;…

[卷积神经网络]FCOS--仅使用卷积的Anchor Free目标检测

项目源码&#xff1a; FCOShttps://github.com/tianzhi0549/FCOS/ 一、概述 作为一种Anchor Free的目标检测网络&#xff0c;FCOS并不依赖锚框&#xff0c;这点类似于YOLOx和CenterNet&#xff0c;但CenterNet的思路是寻找目标的中心点&#xff0c;而FCOS则是寻找每个像素点&…