【数据结构与算法】动态规划法解题20240227

在这里插入图片描述


动态规划法

  • 一、什么是动态规划
  • 二、动态规划的解题步骤
  • 三、509. 斐波那契数
    • 1、动规五部曲:
  • 四、70. 爬楼梯
    • 1、动规五部曲:
  • 五、746. 使用最小花费爬楼梯
    • 1、动规五部曲:

一、什么是动态规划

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

所以动态规划中每一个状态一定是由上一个状态推导出来的

二、动态规划的解题步骤

对于动态规划问题,我将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!
确定dp数组(dp table)以及下标的含义
确定递推公式
dp数组如何初始化
确定遍历顺序
举例推导dp数组

三、509. 斐波那契数

在这里插入图片描述

1、动规五部曲:

这里我们要用一个一维dp数组来保存递归的结果
1、确定dp数组以及下标的含义
dp[i]的定义为:第i个数的斐波那契数值是dp[i]

2、确定递推公式
为什么这是一道非常简单的入门题目呢?
因为题目已经把递推公式直接给我们了:状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];

3、dp数组如何初始化
题目中把如何初始化也直接给我们了,如下:

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

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

class S509:def func(self, n):# 1、创建dp数组,dp[i]:表示第i个数是第i个斐波那契数列dp = [0] * (n+1)# 3、初始化数组状态dp[0] = 0dp[1] = 1# 4、确定遍历顺序for i in range(2, n+1):# 2、确定递推公式dp[i] = dp[i - 1] + dp[i - 2]print(dp)return dp[n]r = S509()
n = 4
print(r.func(n))

四、70. 爬楼梯

简单
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

在这里插入图片描述

1、动规五部曲:

1、确定dp数组以及下标的含义
dp[i]: 爬到第i层楼梯,有dp[i]种方法

2、确定递推公式
如何可以推出dp[i]呢?
从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]的定义,否则容易跑偏。
这体现出确定dp数组以及下标的含义的重要性!
3、dp数组如何初始化
不考虑dp[0]如何初始化,只初始化dp[1] = 1,dp[2] = 2,然后从i = 3开始递推,这样才符合dp[i]的定义。
4、确定遍历顺序
从递推公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,遍历顺序一定是从前向后遍历的

class S70:def func(self, n):if n <= 1:return n# 1、创建dp数组,dp[i]:走到i台阶,一共用dp[i]种方法dp = [0] * (n + 1)# 3、数组初始化dp[1] = 1dp[2] = 2# 4、确定遍历顺序for i in range(3, n + 1):# 2、确定递推公式dp[i] = dp[i - 1] + dp[i - 2]print(dp)return dp[n]r = S70()
n = 4
print(r.func(n))

五、746. 使用最小花费爬楼梯

简单
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
在这里插入图片描述

1、动规五部曲:

1、确定dp数组以及下标的含义
使用动态规划,就要有一个数组来记录状态,本题只需要一个一维数组dp[i]就可以了。
dp[i]的定义:到达第i台阶所花费的最少体力为dp[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]跳呢?
一定是选最小的,所以dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);

3、dp数组如何初始化
看一下递归公式,dp[i]由dp[i - 1],dp[i - 2]推出,既然初始化所有的dp[i]是不可能的,那么只初始化dp[0]和dp[1]就够了,其他的最终都是dp[0]dp[1]推出。
新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的,但从 第0 个台阶 往上跳的话,需要花费 cost[0]。
所以初始化 dp[0] = 0,dp[1] = 0;

4、确定遍历顺序
最后一步,递归公式有了,初始化有了,如何遍历呢?
因为是模拟台阶,而且dp[i]由dp[i-1]dp[i-2]推出,所以是从前到后遍历cost数组就可以了。

class S746:def func(self, cost):# 1、创建dp数组,dp[i]:走到楼梯i,需要最小的花费为dp[i]dp = [0] * (len(cost) + 1)# 3、初始化数组dp[0] = 0  # 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。dp[1] = 0  # 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。# 4、确定遍历顺序for i in range(2, len(cost) + 1):# 2、递推公式# 在第i步,可以选择从前一步(i-1)花费体力到达当前步,或者从前两步(i-2)花费体力到达当前步# 选择其中花费体力较小的路径,加上当前步的花费,更新dp数组dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])return dp[len(cost)]r = S746()
cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
print(r.func(cost))

在这里插入图片描述

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

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

相关文章

qtcreator-ros 安装记录

文章目录 ros_qtc_pluginros_qt_demo参考链接ros_qtc_plugin ROS Qt Creator 插件是专门为 ROS 开发的,通过简化任务和为 ROS 工具创建集中位置来提高开发人员的效率。由于它建立在Qt Creator平台之上,用户可以访问其所有现有功能,例如:语法高亮,代码索引,编辑器(C++,…

Python 实现 CCI 指标计算:股票技术分析的利器系列(8)

Python 实现 CCI 指标计算&#xff1a;股票技术分析的利器系列&#xff08;8&#xff09; 介绍算法解释 代码rolling函数介绍核心代码计算 CCIapply 函数abs 函数 完整代码 介绍 CCI指标的数值波动通常在一个区间内&#xff0c;常见的情况是在-100到100之间。当CCI超过100时&a…

学习 LangChain 的 LCEL

学习 LangChain 的 LCEL 0. 引言1. 基本示例&#xff1a;提示模型输出解析器​1-1. Prompt​1-2. Model1-3. Output parser1-4. Entire Pipeline 0. 引言 LCEL(LangChain Expression Language) 可以轻松地从基本组件构建复杂的链&#xff0c;并支持开箱即用的功能&#xff0c;…

基于springboot+vue的精准扶贫管理系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Spring Bean 相关注解

目录 Autowired Component,Repository,Service, Controller RestController Scope Configuration Autowired 自动导入对象到类中&#xff0c;被注入进的类同样要被 Spring 容器管理比如&#xff1a;Service 类注入到 Controller 类中。 Service public class UserService …

「Qt Widget中文示例指南」如何实现文档查看器?(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 文档查看器是一个显…

IDEA配置有道翻译插件

目录 安装Translation插件有道云配置翻译APIIDEA配置有道翻译引擎 关于IDEA Translation插件中有道智云&#xff08;有道翻译&#xff09;应用ID&#xff0c;密钥申请教程 安装Translation插件 File -> Settings ->Plugins ->搜索Translation ->insatll 有道云…

Ubuntu上Jenkins自动化部署Gitee上SpringBoot项目

文章目录 安装安装JDK安装Maven安装GitNodeJS安装&#xff08;可选&#xff09;安装Jenkins 配置Jenkins为Jenkins更换插件源设置jenkins时区安装插件全局工具配置添加Gitee凭证Gitee项目配置 部署后端1.新建任务2.配置源码管理3.构建触发器4.到Gitee中添加WebHook5.构建环境6.…

RISC-V指令集之RV32C

RISC-V指令集之RV32C 1 指令格式2 RV32C的指令 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 指令格式 RV32C&#xff08;压缩指令&#xff09;的意义&#xff1a; RV32C基于32位寄存器的RISC-V架构&#xff0c;同时增加了压缩指令集&#xf…

RV64 - 64位地址指令

RV64 - 64位地址指令 1 RV64G介绍2 RV64G增加的指令 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 RV64G介绍 RV32I RV32M RV32A RV32F RV32D RV32G&#xff0c;那么RV32G 指令的64 位版本 – RV64G 指令&#xff0c;其示意图&#xff0…

300分钟吃透分布式缓存-08讲:MC系统架构是如何布局的?

系统架构 我们来看一下 Mc 的系统架构。 如下图所示&#xff0c;Mc 的系统架构主要包括网络处理模块、多线程处理模块、哈希表、LRU、slab 内存分配模块 5 部分。Mc 基于 Libevent 实现了网络处理模块&#xff0c;通过多线程并发处理用户请求&#xff1b;基于哈希表对 key 进…

ETH Denver见!来参加DAO的领袖和爱好者的活动吧

我们将和 DAOBase 在美国丹佛举办 DAO 领袖和爱好者的盛会——“去中心化对话&#xff1a;DAO 治理的新时代”活动&#xff01; 随着加密货币和区块链技术的快速发展&#xff0c;DAO 已成为数字经济不可或缺的一部分。目前&#xff0c;已有超过 10 万个 DAO&#xff0c;拥有超…