动态规划(1)斐波那契数列模型

动态规划算法流程:

1、状态表示:

        指的是dp(dynamic programming)表里面的值所表示的含义

        如何得出:1、题目要求

                        2、经验+题目要求

                        3、分析问题的过程中发现重复子问题

2、状态转移方程

        dp[i]等于什么

3、初始化

        保证填表的时候不越界

4、填表顺序

        为了填写当前状态的时候,所需要的状态已经计算过了

5、返回值

        结合题目要求+状态表示

例题

1、1137. 第 N 个泰波那契数 - 力扣(LeetCode)

1、状态表示

        根据题目要求,dp[i]表示第i个泰波那契数的值

2、状态转移方程

        dp[i]依赖于前三个数dp[i-1]、dp[i-2]、dp[i-3]

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

3、初始化

        为了使dp[i-1]、dp[i-2]、dp[i-3]不越界,需要初始化dp[0]=0、dp[1]=1、dp[2]=1

4、填表顺序

        从左向右

5、返回值

        dp[n]

代码实现:
class Solution {public int tribonacci(int n) {  //边界情况if(n==0) return 0;if(n==1||n==2) return 1;//状态方程int[] dp = new int[n+1];//初始化dp[0] = 0;dp[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];}
}
空间优化:滚动数组

O(n)-->O(1)

滚动操作:a = b, b = c, c = d

注意不能先将c = d,不然b就找不到c之前的位置了,要从前向后赋值

class Solution {public int tribonacci(int n) {  //边界情况if(n==0) return 0;if(n==1||n==2) return 1;int a = 0, b = 1, c = 1, d = 0;for(int i = 3;i<=n;i++){d = a + b + c;a = b;b = c;c = d;}return d;}
}

2、面试题 08.01. 三步问题 - 力扣(LeetCode)

题目解析

楼梯有1阶时,直接从起始位置迈一步就到1阶,共1种;有2阶时,可以从起始位置买两步,或者从1阶迈一步,共两种;有三阶时,可以从起始位置迈三步,从1阶迈两步,从二阶迈一步,总共四种。初学者可能会有疑问为什么是四种,因为迈到二阶的方法就两种,从二阶迈一步到三阶的结果还是两种而不是三种,因为这里指的是方法数,不是迈的步数,直接再迈二阶的方法后面加上->3,如下图。所以总方法是前三个迈台阶方法数之和。

1、状态表示

        根据题目加经验:以i位置为结尾,dp[i]表示正好到达第i个台阶总共有dp[i]种方法

2、状态转移方程

        

3、初始化

        因为dp[0]无意义就略去

        dp[1]=1;dp[2]=2;dp[3]=4

4、填表顺序

        从左往右

5、返回值

        dp[n]

细节处理,因为题目要对结果取模,所以要对每一次求和都要取模

dp[i] = ((dp[i-1]+dp[i-2])%(1e9+7)+dp[i-3])%(1e9+7)

代码实现:
class Solution {public int waysToStep(int n) {int Mod = (int)1e9+7;if(n==1 || n==2) return n;if(n==3) return 4;//建表int[] dp = new int[n+1]; //初始化dp[1]=1;dp[2]=2;dp[3]=4;//填表for(int i = 4;i<=n;i++)dp[i] = ((dp[i-1]+dp[i-2])%Mod+dp[i-3])%Mod;//返回值return dp[n];}
}

此题也可以使用滚动数组进行空间优化,与第一题类似。

3、LCR 088. 使用最小花费爬楼梯 - 力扣(LeetCode)

题目解析:

先确定楼顶,如果楼顶为下标[n-1]的位置,则示例1的最小花费为10元,而实际为15,因此楼顶为n的位置。要到达某一位置台阶的花费最小,如果迈两步则总花费为到达i-2的最小花费+cost[i-2],如果迈一步则总花费为到达i-1的最小花费+cost[i-1],因此到此位置的最小花费为迈一步的最小花费与买两步的最小花费的最小值。

示例2:

1、状态表示

        根据题目加经验:以i位置为结尾,dp[i]表示正好到达第i个台阶最小的花费为dp[i]

2、状态转移方程

        dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])

3、初始化

        从起始位置到第一阶和第二阶都不需要花费

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

4、填表顺序

        从左往右

5、返回值

        dp[n]

代码实现:
class Solution {public int minCostClimbingStairs(int[] cost) {int n = cost.length;//建表int[] dp = new int[n+1];//初始化dp[0] = 0;dp[1] = 0;//填表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];}
}

4、91. 解码方法 - 力扣(LeetCode)

题目解析:

解码方式总共有两种,单独解码和两数一起解码

但也有不能解码的情况如下。

算法原理:

1、状态表示

        dp[i]表示以i位置为结尾,解码方法的总数

2、状态转移方程

        根据最近的一步,划分问题,dp[i]=dp[i-1]+dp[i-2]

‘单独解码’成功情况的解释,‘一起解码’同理

3、初始化

dp[0]和dp[1]

4、填表顺序

从左往右

5、返回值

dp[n-1]

代码实现:
class Solution {public int numDecodings(String s) {//1、创建dp表int n = s.length();int[] dp = new int[n];//2、初始化if(s.charAt(0)!='0') dp[0] = 1;if(n==1) return dp[0]; //边界情况char a = s.charAt(0);char b = s.charAt(1);if(b!='0'&&a!='0') dp[1]+=1;int t = (a-'0')*10+(b-'0');if(t>=10&&t<=26) dp[1]+=1;//3、填表for(int i = 2;i<n;i++){if(s.charAt(i)>'0'&&s.charAt(i)<='9')  dp[i] += dp[i-1];t = (s.charAt(i-1)-'0')*10+(s.charAt(i)-'0');if(t>=10&&t<=26)  dp[i] += dp[i-2];}//4、返回值return dp[n-1];}
}

我们发现初始化的代码很复杂并且逻辑和填表的代码类似,因此我们可以添加辅助节点的方法来简化代码。

处理边界问题以及初始化的技巧:

虚拟位置初始化:为了以后填表正确,dp[0]需要为1,因为如果dp[2]和dp[1]填表正确,那么前面的填表也是正确的,如果为0说明前面解码不成功,因此要为1.

下标映射关系:根据上图,初始化只处理了s[0], s[1]并未处理,因此填表处理时的s下标为i-1

class Solution {public int numDecodings(String s) {int n = s.length();int[] dp = new int[n+1];dp[0] = 1;if(s.charAt(0)!='0') dp[1] = 1;else return 0;for(int i = 2;i<=n;i++){if(s.charAt(i-1)>'0'&&s.charAt(i-1)<='9')  dp[i] += dp[i-1];if((s.charAt(i-2)-'0')*10+(s.charAt(i-1)-'0')>=10&&(s.charAt(i-2)-'0')*10+(s.charAt(i-1)-'0')<=26)  dp[i] += dp[i-2];}return dp[n];}
}

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

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

相关文章

dbt doc 生成文档命令示例应用

DBT提供了强大的命令行工具&#xff0c;它使数据分析师和工程师能够更有效地转换仓库中的数据。dbt的一个关键特性是能够为数据模型生成文档&#xff0c;这就是dbt docs命令发挥作用的地方。本教程将指导您完成使用dbt生成和提供项目文档的过程。 dbt doc 命令 dbt docs命令有…

案例实践 | 以长安链为坚实底层,江海链助力南通民政打造慈善应用标杆

案例名称-江海链 ■ 实施单位 中国移动通信集团江苏有限公司南通分公司、中国移动通信集团江苏有限公司 ■ 业主单位 江苏省南通市民政局 ■ 上线时间 2023年12月 ■ 用户群体 南通市民政局、南通慈善总会等慈善组织及全市民众 ■ 用户规模 全市近30家慈善组织&#…

查询hive数据库报错Required field ‘type‘ is unset

文章目录 一、报错内容TProtocolException: Required field ‘type’ is unset 一、报错内容TProtocolException: Required field ‘type’ is unset org.apache.thrift.protocol.TProtocolException: Required field ‘type’ is unset! Struct:TPrimitiveTypeEntry(type:nu…

leetcode二叉树(八)-二叉树的最大深度

题目 104.二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&…

C语言二级刷题

&#xff08;1&#xff09;考点9 &#x1f601; 1. #include <stdio.h> #define S(x) x*x #define T(x) S(x)*S(x) main() { int k5, j2;printf("%d,%d\n", S(kj),T(kj)); }本题考查宏定义 以kj直接代替x 则S(kj)kj*kj 2. #include <stdio.h> …

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波 前言MPU6050寄存器代码详解mpu6050.cmpu6050.h 使用说明 前言 本篇文章基于卡尔曼滤波的原理详解与公式推导&#xff0c;来详细的解释下如何使用卡尔曼滤波来解算MPU6050的姿态 参考资料&#xff1a;Github_mpu6050 MPU6050寄存器…

项目管理软件真的能让敏捷开发变得更简单吗?

敏捷开发是一种以快速交付和适应变化为核心特点的软件开发方法。其特点包括尽早并持续交付、能够驾驭需求变化、版本周期内尽量不加任务、业务与开发协同工作、以人为核心、团队配置敏捷等。 例如&#xff0c;尽早并持续交付可使用的软件&#xff0c;使客户能够更早地体验产品…

【算法篇】动态规划类(4)——子序列(笔记)

目录 一、Leetcode 题目 1. 最长递增子序列 2. 最长连续递增序列 3. 最长重复子数组 4. 最长公共子序列 5. 不相交的线 6. 最大子序和 7. 判断子序列 8. 不同的子序列 9. 两个字符串的删除操作 10. 编辑距离 11. 回文子串 12. 最长回文子序列 二、动态规划总结 …

[Linux#67][IP] 报头详解 | 网络划分 | CIDR无类别 | DHCP动态分配 | NAT转发 | 路由器

目录 一. IP协议头格式 学习任何协议前的两个关键问题 IP 报头与有效载荷分离 分离方法 为什么需要16位总长度 如何交付 二. 网络通信 1.IP地址的划分理念 2. 子网管理 3.网络划分 CIDR&#xff08;无类别域间路由&#xff09; 目的IP & 当前路由器的子网掩码 …

外包干了3周,技术退步太明显了。。。。。

先说一下自己的情况&#xff0c;大专生&#xff0c;21年通过校招进入武汉某软件公司&#xff0c;干了差不多3个星期的功能测试&#xff0c;那年国庆&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我才在一个外包企业干了3周的功…

C++11标准 future异步线程库

原文链接&#xff1a;C11标准 future异步线程库 前言 c标准有很多的版本,比较知名的如c98是第一版c标准,提供了c最底层的支持. 后面的c11和c20每个版本都会给c带来新特性. 而线程就是是c11最重要的特性. 虽然c98有pthread库,但是c11的thread有更好的跨平台能力,最重要的是c1…

神经网络构建与训练深度学习模型全过程(PyTorch TensorFlow)

神经网络构建与训练深度学习模型全过程&#xff08;PyTorch & TensorFlow&#xff09; 目录 &#x1f517; 什么是神经网络&#xff1a;基础架构与工作原理&#x1f9e9; 构建简单的神经网络&#xff1a;层次结构与激活函数&#x1f680; 前向传播&#xff1a;神经网络的…

基于Handsontable.js + Excel.js实现表格预览和导出功能(公式渲染)

本文记录在html中基于Handsontable.js Excel.js实现表格预览、导出、带公式单元格渲染功能&#xff0c;在这里我们在html中实现&#xff0c;当然也可以在vue、react等框架中使用npm下载导入依赖文件。 Handsontable官方文档 一、开发前的准备引入相关依赖库 <!DOCTYPE ht…

React 探秘(一):fiber 架构

文章目录 背景React 采用 fiber 主要为了解决哪些问题&#xff1f;性能问题&#xff1a;用户体验问题&#xff1a; 为什么在 React 15 版本中性能会差&#xff1a;浏览器绘制原理&#xff1a;react 15 架构和问题 那么 fiber 怎么解决了这个问题&#xff1f;任务“大”的问题递…

微服务经典应用架构图

从网上找了一个经典的微服务架构图&#xff0c;资料来源于若依开源系统的ruoyi-cloud&#xff0c;仅供参考&#xff01;

面向城市运行“一网统管”的实景三维示范应用

在新型智慧城市建设的浪潮中&#xff0c;实景三维技术正成为推动城市治理现代化的重要力量。“一网统管”作为城市运行管理的新理念&#xff0c;强调了跨部门协作和数据共享&#xff0c;而实景三维技术为此提供了强有力的支撑。本文将探讨实景三维技术如何赋能“一网统管”&…

Linux笔记---vim的使用

1. vim的基本概念 Vim是一款功能强大的文本编辑器&#xff0c;它起源于Unix系统的vi编辑器&#xff0c;并在其基础上进行了许多改进和增强。 Vim以其高效的键盘操作、高度的可定制性和强大的文本处理能力而闻名&#xff0c;尤其受程序员和系统管理员的欢迎。 Vim支持多种模式…

Flutter框架学习计划

Flutter是一个由Google开发的开源移动应用开发框架&#xff0c;它允许开发者使用同一套代码库构建跨平台的移动、Web和桌面应用。以下是Flutter的背景、设计理念以及核心优势的详细介绍&#xff1a; 背景 Flutter最初发布于2017年&#xff0c;它的开发目的是为了提供一个高性…

javascript叉乘方法计算多边形的面积

多边形的面积可以通过对其顶点进行叉乘&#xff08;Cross Product&#xff09;来计算。这种方法基于向量分析&#xff0c;适用于简单多边形&#xff0c;尤其是当多边形的顶点按顺序排列时&#xff08;例如&#xff0c;顶点按照顺时针或逆时针方向排列&#xff09;。 计算原理 …

cmake 编译 01

CMakeLists.txt cmake_minimum_required(VERSION 3.10)project(MyProject)set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True)# 如果顶层 CMakeLists.txt 文件中使用了 add_subdirectory() 命令&#xff0c;CMake 会进入指定的子目录&#xff0c;并处理该目录…