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

算法【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];}
}

小结

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

相关文章:

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

动态规划 动态规划的思路一共有五个步骤&#xff1a; 状态表示&#xff1a;由经验和题目要求得出&#xff0c;这个确实有点抽象&#xff0c;下面的题目会带大家慢慢感受状态标识状态转移方程初始化&#xff1a;避免越界访问 dp 表&#xff0c;所以在进行填表之前我们要预先填…...

idea连接docker并构建镜像

安装docker 安装docker idea连接docker 安装docker插件 设置docker连接 设置docker.exe 这个docker.exe是为了运行docker&#xff0c;可以通过安装docker desktop获取 docker desktop下载地址 右键图标找到文件位置 在同级的resource中 编写Dockerfile # 使用官方 Nginx…...

百度如何打造AI原生研发新范式?

&#x1f449;点击即可下载《百度AI原生研发新范式实践》资料 2024年10月23-25日&#xff0c;2024 NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。本届大会邀请了工业界和学术界的专家&#xff0c;优秀的工程师和产品经理&#xff0c;以及其它行…...

RedisTemplate类中的常用方法粗解(简单明了,预计5分钟看完)

在阅读项目代码过程中发现引用RedisTemplate 的方法操作redis时&#xff0c;都会有一些特定的ops &#xff0c;对此好奇就查资料的情况下有了本博客。 操作之前付一张我们项目中的用到的地方的图 另外本文中的语言用到的是Java&#xff0c;附上试验用到的redisTemplete依赖 <…...

鸿蒙ArkTS中的布局容器组件(Column、Row、Flex、 Stack、Grid)

在鸿蒙ArkTS中&#xff0c;布局容器组件有很多&#xff0c;常见的有&#xff1a;   ⑴ Column&#xff1a;&#xff08;垂直布局容器&#xff09;&#xff1a;用于将子组件垂直排列。   ⑵ Row&#xff1a;&#xff08;水平布局容器&#xff09;&#xff1a;用于将子组件水…...

显存占用 显存测试

目录 显存测试 显存占用示例 一个模型多卡占用 显存测试 import torch# 计算张量的大小&#xff08;例如&#xff1a;每个 float 占用 4 字节&#xff09; # 40GB 40 * 1024 * 1024 * 1024 字节 # 每个 float 4 字节&#xff0c;因此需要的 float 数量为 (40 * 1024 * 1024…...

快速入门CSS

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗 如有错误&#xff0c;欢迎指出~ 目录 CSS css的三种引入方式 css书写规范 选择器分类 标签选择器 class选择器 id选择器 复合选择器 通配符选择器 color颜色设置 border边框设置 width/heigth 内/外边距 C…...

AcWing 1073 树的中心 树形dp (详解)

这道题目非常有新意&#xff0c;在过去&#xff0c;我们通常先访问子节点去更新父节点的状态&#xff0c;但是这道题我们还需要从父节点去更新子节点。 我们可以想象为向上和向下两个方向&#xff0c;我们任取一点&#xff0c;先向下走&#xff0c;再回来更新上面的点&#xf…...

modelscope下载Qwen2.5 72B 模型方法

conda create -n modelscope python=3.10 conda activate modelscopepip install modelscope执行这个python代码: from modelscope.hub.snapshot_download import snapshot_download# 下载模型到当前路径 model_dir = snapshot_download(...

重学SpringBoot3-整合 Elasticsearch 8.x (二)使用Repository

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 整合 Elasticsearch 8.x &#xff08;二&#xff09;使用Repository 1. 环境准备1.1 项目依赖1.2 Elasticsearch 配置 2. 使用Repository的基本步骤2.1 创建实体类2.2 创…...

为什么说模拟电路的难点就在开通过程和关断过程?难在什么地方?

模拟电路中开通过程和关断过程之所以困难&#xff0c;主要有以下几个方面的原因&#xff1a; 1. 瞬态响应特性复杂 - 在开通和关断瞬间&#xff0c;电路中的电流和电压会发生快速变化&#xff0c;产生复杂的瞬态响应。这些瞬态响应可能包含过冲、下冲、振铃等现象&#xff0c;…...

CubeIDE BUG-project‘hello‘has no explict encoding set hello

projecthellohas no explict encoding set hello 解决方法&#xff1a; 点击红色处注册账号后登录&#xff0c;删除原本文件后重新生成即可。...

在线PDF转图片网站

https://www.ilovepdf.com/download/qgxkmbzgxt6yb3s8l9f7fc3q9606hq0bfh4b33mnrf3p7tp8l0d4qy386b5dxqwjbhq7j3j4tp20m4dnb89wA9jjw25br1gtAw42l0m1sq047nvld4qqrm8kzjplkAhw9458p4wjgbmn08g49l23c1khsggdx4A7z3m9xh19mgzdlllyA6r1/52 在线excel转图片 https://www.zamzar.c…...

ps和top的区别

时间上的区别&#xff1a; ps是静态查看进程而top是动态持续监控进程 功能上的区别 ps只是查看进程,top还可以监视系统性能,如平均负载,cpu和内存的消耗 ps 常用格式&#xff1a;ps -ef &#xff08;ef简洁aux详细 System &#xff36;风格和BSD 风格&#xff09; | grep P…...

自动驾驶上市潮中,会诞生下一个“英伟达”吗?

站上科技创新潮头的企业总是备受资本青睐。20世纪开始&#xff0c;从IT到互联网&#xff0c;IBM、英特尔、微软、苹果等各大科技巨头&#xff0c;你方唱罢我登场。 近几年&#xff0c;人工智能成为资本市场新传奇故事的孕育之地。今年10月&#xff0c;英伟达市值首度突破3.5万…...

CSS 计数器:深入解析与高级应用

CSS 计数器&#xff1a;深入解析与高级应用 CSS 计数器是前端开发中一个强大但经常被忽视的功能。它们允许开发者创建和管理自定义的计数序列&#xff0c;这在处理复杂文档结构时尤其有用。本文将深入探讨 CSS 计数器的原理、用法&#xff0c;并展示一些高级应用示例。 什么是…...

【真题笔记】15年系统架构设计师要点总结

【真题笔记】15年系统架构设计师要点总结 分布式数据库中各种透明RAID 5IPv6 IPv4电子商务系统项目配置管理IPO图&#xff08;输入加工输出图&#xff09;桥接模式的UML图面向对象设计原则软件测试 在15年真题练习中&#xff0c;对错题模棱两可的考点进行重点记录与内容延申。…...

斗破C++编程入门系列之三十九:多态性:纯虚函数和抽象类(四星斗师)

斗破C目录&#xff1a; 斗破C编程入门系列之前言&#xff08;斗之气三段&#xff09; 斗破C编程入门系列之二&#xff1a;Qt的使用介绍&#xff08;斗之气三段&#xff09; 斗破C编程入门系列之三&#xff1a;数据结构&#xff08;斗之气三段&#xff09; 斗破C编程入门系列之…...

目前美国的互联网环境

随着科技的迅猛发展&#xff0c;互联网已经成为了现代社会不可或缺的一部分。作为全球科技创新的领导者之一&#xff0c;美国在互联网领域拥有着丰富的资源和先进的技术。本文将对美国目前的互联网环境进行探讨&#xff0c;包括网络基础设施、网络安全、数字经济以及互联网对社…...

从最小作用量原理推导牛顿三大定律

从最小作用量原理推导牛顿三大定律 引言 在物理学中&#xff0c;牛顿三大定律是描述经典力学中物体运动的基本定律。然而&#xff0c;这些定律并不是孤立存在的&#xff0c;它们可以从一个更为普遍的原理——最小作用量原理中推导出来。最小作用量原理是一个深刻而优雅的理论…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...