算法【Java】—— 动态规划之斐波那契数列模型

动态规划

动态规划的思路一共有五个步骤:

  1. 状态表示:由经验和题目要求得出,这个确实有点抽象,下面的题目会带大家慢慢感受状态标识
  2. 状态转移方程
  3. 初始化:避免越界访问 dp 表,所以在进行填表之前我们要预先填写好一些数据。
  4. 填表顺序
  5. 返回值

动态规划的代码书写步骤:
建表,初始化,填表,返回值,最后中间可能由细节的处理

实战演练

第N个泰波那契数

在这里插入图片描述


解析:对于一维的数据我们的状态表示基本是题目要求什么状态表示就是什么,上面这个题目要求我们求出第N 个泰波那契数,那么我们的 dp 表就定义为 dp[i] 表示 第 i 个 泰波那契数。

状态转移方程:题目已经很贴心告诉我们 T(n + 3) = T(n) + T(n+1) + T(n+2),我们稍微转化一下:T(n) = T(n-3) + T(n-2) + T(n-1),即 dp[i] = dp[i-1] + dp[i-2] + dp[i-3]

初始化:我们在求 dp[0]、dp[1]、dp[2] 的时候是不能直接使用状态转移方程来求取的,否则就会发生数组越界,所以我们要在填表之前把着三个 dp 值给预设好,dp[0] = 0, dp[1] = dp[2] = 1

填表顺序:由于在初始化我们已经填好了前面三个数字:dp[0]、dp[1]、dp[2],所以我们从 i == 3 开始填表,从左向右这个顺序把 dp 表填满。

返回值:题目要求我们求 第N 个泰波那契数,正好我们的 dp 表的状态表示也是这个,所以直接返回 dp[n] .

细节处理:如果 n = 0 / 1 的时候,直接返回,不需要初始化和填表了,避免数组访问越界,举个例子:假设 n 等于 0,也就是说 dp 表其实就只有一个位置,但是你初始化要初始三个位置,数组妥妥越界访问。

class Solution {public int tribonacci(int n) {//建表int[] dp = new int[n + 1];//细节处理if(n == 0 || n == 1) return n;//初始化dp[0] = 0; dp[1] = 1; dp[2] = 1;//填表for(int i = 3; i <= n; i++) {dp[i] = dp[i-1] + dp[i-2] + dp[i-3];}//返回值return dp[n];}
}

三步问题

在这里插入图片描述


解析:
状态表示:一维数组形式,我们通常以题目要求出来思考状态表示,如果这个状态表示不能推导出状态转移方程那就再换别的状态表示,这里我们直接定义状态表示为 dp[i] 表示上到第 i 个台阶一共有多少中方式。

状态转移方程:上到 第 i 个台阶有多少种方式 等于上到第 i - 1 个台阶需要多少种方式 + 上到第 i - 2 个台阶需要多少种方式 + 上到第 i - 3 个台阶需要多少种方式,为什么是三种台阶方式相加,回到题目,一次可以跨一步 / 两步 / 三步。

初始化,我们需要将 dp[1] = 1, dp[2] = 2,dp[3] = 4,设置好,同样这里也有细节要处理,如果 n == 1 或者 n == 2 直接返回即可。

填表顺序:从 i == 4 开始填,从左到右

返回值:直接返回 dp[n]

这道题还有一个小细节,就是结果可能很大,我们需要将结果 取模 1000000007,在每次进行加法的时候都去取模即可。

class Solution {public int waysToStep(int n) {//建表int[] dp = new int [n+1];//细节处理if(n == 1 || n == 2) return n;//初始化dp[1] = 1; dp[2] = 2; dp[3] = 4;//填表for(int i = 4; i <= n; i++) {dp[i] = ((dp[i-1] + dp[i-2]) % 1000000007 + dp[i-3]) % 1000000007;}//返回值return dp[n]; }
}

使用最小花费爬楼梯

在这里插入图片描述


解析:
状态表示:这里还是一个一维形式的数组,我们定义 dp[i] 表示达到 第 i 个台阶所需要的最小花费。

状态转移方程:由于每次可以走一个或者两个台阶,所以我们要推导出 dp[i] ,就要知道 dp[i-1] + cost[i-1] 和 dp[i-2] + cost[i-2] 的最小花费是什么。这个为什么要加上 cost[i-1] / cost[i-2] ? 因为 dp[i] 表示达到 i 台阶需要的最小花费,你如果从 i 台阶往上走就需要先支付 i 台阶的费用也就是 cost[i]。

初始化:dp[1] = 0,dp[2] = 0,由于Java创建数组的时候默认值就是 0,所以可以不进行初始化了,但是细节还是要处理的,如果 n == 0 || n == 1 直接返回 n。

填表顺序:从 i == 2 开始从左往右填

返回值:dp[n]

class Solution {public int minCostClimbingStairs(int[] cost) {//建表int n = cost.length;int[] dp = new int[n+1];//细节处理if(n == 0 || n == 1) return n;//填表for(int i = 2; i <= n; i++) {dp[i] = Math.min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);}return dp[n];}
}

解码方式

在这里插入图片描述
在这里插入图片描述


解析:
状态表示:到达第 i 个字符的时候一共有多少种编码。

状态转移方程:首先我们先进行单字符解码,如果一个字符的数值不等于 0 的时候,是可以单独解码的,这时候 dp[i] += dp[i-1],把前一个字符有多少种解码方式加起来。
然后就是和前一个字符看是否能共同解码,首先要求前一个字符不能为 0, 其次两个字符组成的数字要小于等于 26,如果都满足,说明可以和前一个字符进行合并解码,dp[i] += dp[i-2],把前前一个字符的解码方式相加起来。

初始化:先处理前两个字符的 dp 值,并且有一个细节,如果 字符串长度为 1, 是不能进行第二个字符的解码的,需要直接返回。

填表顺序:从 i == 2 开始从左往右填写。

返回值:dp[n-1]

还有一个细节:如果一个dp 值为 0 的时候,不需要进行后面的填表操作,此时已经无法对字符串进行解码了,直接返回 0 即可。

class Solution {public int numDecodings(String ss) {//建表int n = ss.length();int[] dp = new int [n];char[] s = ss.toCharArray();//细节处理与初始化if(s[0] - '0' != 0) {dp[0] = 1;} else {dp[0] = 0;}if(n == 1 || dp[0] == 0) {return dp[0];}//处理第二个字符if(s[1] - '0' != 0) dp[1]++;if(s[0] - '0' != 0 && (s[0] - '0') * 10 + (s[1] - '0') <= 26) dp[1]++;//填表for(int i = 2; i < n; i++) {if(s[i] - '0' != 0) dp[i] += dp[i-1];if(s[i-1] - '0' != 0 && 10 * (s[i-1] - '0') + (s[i] - '0') <= 26) dp[i] += dp[i-2];if(dp[i] == 0) return 0;}return dp[n-1];}
}

小结

面对一维形式的数据的时候,一般我们的状态表示直接从题目要求中获取。
在初始化之前一定要注意没有细节需要处理。

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

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

相关文章

kafka使用指南

文章目录 前言特点架构一、zookeeper安装配置二、kafka安装配置三、快去试一下吧&#xff01;下一章:kafka命令之分区接入创建删除 前言 随着大数据时代的到来&#xff0c;高吞吐量的分布式发布订阅消息系统kafka得到了极大的应用&#xff0c;它具有高吞吐量、 特点 高吞吐量…

Windows 服务器中用户的分类

Windows 服务器中用户的分类 本地用户&#xff08;只能在本地登录&#xff09;如果你的服务器升级为域成员服务器&#xff0c;即刻失去本地服务。 漫游用户&#xff08;域用户就是漫游用户&#xff0c;可用在域内的任何一个设备上、且在权限允许的范围内进行登录和资源使用。 …

基于YOLO11/v10/v8/v5深度学习的建筑墙面损伤检测系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

Sublime Text 的PHP格式化插件phpfmt 的 setting 配置参数说明

phpfmt.sublime-settings 是 Sublime Text 中 phpfmt 插件的配置文件&#xff0c;用于定义代码格式化的各种参数。以下是一些常见的配置参数及其说明&#xff1a; 1、version 指定配置文件的版本&#xff0c;根据 phpfmt 插件的版本&#xff0c;此值可能有所不同。 2、php_b…

Oracle视频基础1.2.1练习

1.2.1 需求&#xff1a; 完整格式查看所有用户进程判断oracle启动状态 连接sqlplus不登陆 以sysdba身份登陆&#xff0c;通过登陆信息判断oracle启动状态 启动数据库&#xff0c;查系统全局区动态组件表 使用shell&#xff0c;启动监听然后返回sql ps -ef sqlplus /nolog con…

Ajax学习

目录 一、是什么 二、jQuery.ajax 三、初实现 四、再实现 五、应用 一、是什么 AJAX&#xff1a;Asynchronous JavaScript and XML&#xff08;异步的JavaScript和XML&#xff09; 是一种在无需重新加载整个网页的情况下&#xff0c;能够更新部分网页的技术 应用&#…

音频中sample rate是什么意思?

‌sample rate‌在数字信号处理中&#xff0c;指的是‌采样频率‌&#xff0c;即每秒钟从连续信号中抽取的样本数量。采样频率越高&#xff0c;信号的还原度越高&#xff0c;但同时也会增加计算负担和存储需求‌。 实际应用场景 在音频处理中&#xff0c;设置合适的采样率可以…

RabbitMQ客户端应用开发实战

这一章节我们将快速完成RabbitMQ客户端基础功能的开发实战。 一、回顾RabbitMQ基础概念 这个RabbitMQ的核心组件&#xff0c;是进行应用开发的基础。 二、RabbitMQ基础编程模型 RabbitMQ提供了很多种主流编程语言的客户端支持。这里我们只分析Java语言的客户端。 上一章节提…

【光交换器件】

一、ROADM ROADM节点通常由波长选择开关&#xff08;WSS&#xff09;和其他模块组成。 ROADM分类 光网络交叉能力分类 Colorless&#xff08;波长无关&#xff09; Directionless&#xff08;方向无关&#xff09; Contentionless&#xff08;竞争无关&#xff09; Flexi-G…

docker的安装配置与基本简单命令

目录 1.docker简介 2.docker安装 2.1使用root用户登陆 更新yum源 2.2安装依赖 2.3设置yum源 更新yum源索引 2.4安装docker 2.5启动并且设置开机自启动 2.6验证安装是否成功 2.7配置docker加速器 2.8重启docker服务 3.docker简单使用 3.1下载镜像 3.2列出…

第72期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

Fx-LMS 单片机

功能&#xff1a;主动降噪控制器 开发板连接麦克风&#xff0c;通过ADC或其他方式采集声音信号。采集到的声音信号经过开发板内置的Fx-LIIS主动降噪算法处理&#xff0c;生成反向声波信号&#xff0c;并通过DAC输出至扬声器进行播放。通过反向声波与原声波叠加&#xff0c;达到…

web前端3D旋转相册(附完整代码)

效果图 当鼠标移动到目标时&#xff0c;外层的图片会张开&#xff0c;外面的图片修改透明度为0.5达到想要的效果。 完整代码 HTML部分 这里用的是绝对路径&#xff0c;一般建议使用相对路径&#xff08;..代表上一级&#xff0c;.代表当前文件夹&#xff09; <!DOCTYPE …

新老项目不同node版本,使用nvm控制node版本切换(mac、window)

window系统电脑的链接&#xff1a;https://blog.csdn.net/qq_40269801/article/details/136450961 以下是mac版本的操作方式&#xff1a; 1、打开终端 克隆 NVM 仓库&#xff1a; git clone https://github.com/nvm-sh/nvm.git ~/.nvm 2、运行安装脚本&#xff1a; cd ~/.n…

2024双11买什么东西比较好?2024年双十一必买清单大全!

2024年双十一到底哪些东西值得入手&#xff1f;今天总结了超全双十一值得入手的单品汇总&#xff01;随着一年一度的双十一购物狂欢节临近&#xff0c;各大电商平台纷纷推出各种促销活动&#xff0c;吸引了无数消费者的关注。在这场全民参与的购物盛宴中&#xff0c;如何在众多…

vi —— 终端中的编辑器

目标 vi 简介打开和新建文件三种工作模式常用命令分屏命令常用命令速查图 01. vi 简介 1.1 学习 vi 的目的 在工作中&#xff0c;要对 服务器 上的文件进行 简单 的修改&#xff0c;可以使用 ssh 远程登录到服务器上&#xff0c;并且使用 vi 进行快速的编辑即可常见需要修改…

安装fpm,解决*.deb=> *.rpm

要从生成 .deb 包转换为 .rpm 包&#xff0c;可以按照以下步骤修改打包脚本 1. 使用 fpm 工具 fpm 是一个强大的跨平台打包工具&#xff0c;可以将 .deb 包重新打包成 .rpm&#xff0c;也可以直接从源文件打包成 .rpm。 安装 fpm sudo apt-get install ruby-dev sudo gem in…

web文件包含include

php伪协议 在 PHP 中&#xff0c;伪协议&#xff08;Pseudo Protocols&#xff09; 也被称为 流包装器&#xff0c;这些伪协议以 php:// 开头&#xff0c;后面跟着一些参数&#xff0c;用于指定 要执行的操作 或 需要访问的资源。 伪协议表明这些协议并不是一个 真实的外部协议…

QChart中柱形图的简单使用并实现【Qt】

预备工作 如果qt没下载去下载一个&#xff0c;下载太慢了可以试试它[点击跳转]  (https://blog.csdn.net/qq_19319481/article/details/131655379)。   如果已经下载了qt发现自己的组件中没有QCharts&#xff0c;可以去试试它点击跳转。 都搞定了以后在pro文件里面添加QT …

视频点播系统扩展示例

更多的前端页面&#xff08;如视频详情页、用户注册页等&#xff09;。更复杂的业务逻辑&#xff08;如视频评论、搜索功能等&#xff09;。安全性和权限管理&#xff08;如用户角色管理、权限控制等&#xff09;。其他技术细节&#xff08;如文件上传、分页查询等&#xff09;…