【动态规划】是泰波那契数,不是斐波那契数

2023-10-11 12:44

本文主要是介绍【动态规划】是泰波那契数,不是斐波那契数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

在这里插入图片描述

Problem: 1137. 第 N 个泰波那契数

文章目录

  • 题目解读
  • 解题方法
    • dp动态规划
    • 迭代优化✔
  • 复杂度
  • Code

题目解读

首先我们来解读一下本题的意思🔍

1.jpg

  • 相信读者在看到【泰波那契数】的时候,不禁会联想到【斐波那契数】,它们呢是一对孪生兄弟,这个 泰波那契数 相当于是 斐波那契数 的加强版
  • 我们首先可以来看到这个递推公式Tn+3 = Tn + Tn+1 + Tn+2,读者可能看不太懂,我们将其做一个转换为Tn = Tn-1 + Tn-2 + Tn-3,即把所有n都统一-3那么第N个泰波那契数就等于前面3个泰波那契数的和

2.jpg

  • 看到上面的T3,就是前3个数的和等于2,以此类推T4就是T1 + T2 + T3 = 4

解题方法

看完了上面对于题目的分析之后,下面我将介绍两种解法

dp动态规划

首先的话就是本题需要掌握的重点即【动态规划】的解法,我们要分成五步去求解

  1. 状态表示
  • 首先读者要清楚的是在求解动态规划的题目时,都是需要一个dp数组的,那么对于【状态表示】的含义就是dp表里的值所表示的含义

3.jpg

那这个状态表示是怎么来的呢?

① 第一个呢就是按照题目要求来,dp[i]表示的就是第i个泰波那契数列的值

② 第二个呢则是需要读者有丰富的刷题经验,可以读完题目之后就得出对应的结果

③ 第三个呢则是在分析问题的过程中,发现重复的子问题

如果读者之前有接触过类似的动态规划问题的话,就会看到一些题解里讲:这道题的 状态表示 是怎样的,然后就直接讲本题的 状态表示方程,根本没有说这道题的状态表示是怎么来的。这个得来的过程我会在其他动态规划的题目中进行讲解

👉 所以读者在解类似的问题时一定要知道下面的这个【状态表示方程】是怎么来的,做到 “ 知其然,知其所以然 ”


  1. 状态表示方程
  • 那么本题的状态表示方程为dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
  1. 初始化
  • 在清楚【状态表示方程】该如何写之后,我们要去做的就是对这个dp数组做一个初始化的工作。看到下面的这个dp数组,如果在一开始我们的下标取值就到0的话,那么i - 1i - 2i - 3这些就会造成 越界

4.jpg

  • 因此我们要给这个dp数组去做一个初始化,具体的就是对前三个数据即dp[0]dp[1]dp[2]分别初始化为【0】【1】【1】,那我们在后面遍历计算的时候就只需要从下标为3的位置开始即可
 dp[0] = 0, dp[1] = dp[2] = 1;
  1. 填表顺序
  • 接下去的话就是把dp数组按照 状态表示方程 给填充好即可
for(int i = 3; i <= n; ++i)
{// 状态转移方程dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}
  1. 返回值
  • 最后一块我们处理返回值,根据题目要求我们是要返回【第 n 个泰波那契数 Tn 的值】,所以直接 return dp[n] 即可

但是呢,若只考虑上面的这一些,在提交的时候是会出现越界的情况,因为在题目中给出的n的范围为[0, 37],因此对于dp[0]还好说,但对于后面的数据就会出现越界的情况

5.jpg

因此我们还需要去考虑一些边界的问题

// 边界问题处理
if(n == 0)  return 0;
if(n == 1 || n == 2)    return 1;

👉 整体代码会在最后给出

迭代优化✔

看完上面这一种,我们再来看看其是否可以去做一个优化

  • 如果读者有接触过迭代算法的话,应该很快能想到本题的思路,因为是三个三个去做的累加,所以我们在这里可以定义三个变量abc,它们累加后的值可以放到变量d

6.jpg

  • 因此在累加完一轮之后,我们就需要去做一个迭代的操作
a = b; b = c; c = d;

7.jpg

  • 那么在最后我们所需要返回的值就是这个d
return d;

复杂度

  • 时间复杂度:

对于第一种dp的解法,其时间复杂度为 O ( n ) O(n) O(n),而对于第二种迭代的解法时间复杂度为 O ( 1 ) O(1) O(1)

  • 空间复杂度:

对于第一种dp的解法,其空间复杂度为 O ( n ) O(n) O(n),而对于第二种迭代的解法时间复杂度为 O ( 1 ) O(1) O(1)

👉 所以就这么对比下来迭代优化的方法还是值得大家去掌握的

Code

首先是第一种dp动态规划的解法

class Solution {
public:int tribonacci(int n) {// 边界问题处理if(n == 0)  return 0;if(n == 1 || n == 2)    return 1;// 1.创建dp表vector<int> dp(n + 1);// 2.初始化dp[0] = 0, dp[1] = 1, dp[2] = 1;// 3.填表for(int i = 3; i <= n; ++i){// 状态转移方程dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];}// 4.返回值return dp[n];}
};

然后的话是第二种利用迭代优化的方法

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;}
};

在这里插入图片描述

这篇关于【动态规划】是泰波那契数,不是斐波那契数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/188125

相关文章

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现动态封禁IP的步骤指南

《Nginx实现动态封禁IP的步骤指南》在日常的生产环境中,网站可能会遭遇恶意请求、DDoS攻击或其他有害的访问行为,为了应对这些情况,动态封禁IP是一项十分重要的安全策略,本篇博客将介绍如何通过NG... 目录1、简述2、实现方式3、使用 fail2ban 动态封禁3.1 安装 fail2ban3.2 配