动态规划之第 N 个泰波那契数/三步问题【leetCode】【算法】

动态规划动态规划之第 N 个泰波那契数/三步问题

  • 动态规划
  • LeetCode题目
    • 第 N 个泰波那契数
      • 求解1
      • 求解2(滚动数组)
    • 三步问题
      • 求解1
      • 求解2(滚动数组)

动态规划

  如果问题是由重叠的子问题构成的,那就可以用动态规划(dynamic programming)来解决它。

  在求解动态规划问题的时候,我们需要思考以下5个步骤:

  1. 状态表示这是最重要的):我们会创建一个dp表,将较小问题的解放在表中,这样我们就会得到原始问题的解,所以状态表示就是清楚dp表里面某个位置所表示的含义。
  2. 状态转移方程最难的):也就是从题干中找到关于dp[i]的等式。
  3. 初始化:填表时,保证不越界。当求解问题时,需要知道较小问题的解,较小问题的解一定也是通过更小问题的解求得的,所以我们必须知道最初问题的解,以此来求得较大问题的解,这就需要我们限定dp[i]中i的取值范围。
  4. 填表顺序:当我们求解当前问题时,需要知道所需较小子问题的解,这就需要我们先求解得到较小子问题的解,这就是填表顺序。
  5. 返回值:题目要求+状态表示

  在代码中的体现为四个步骤:1. 创建dp表。 2. 初始化。 3. 填表。 4. 返回。

LeetCode题目

第 N 个泰波那契数

1137. 第 N 个泰波那契数
在这里插入图片描述

求解1

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

求解2(滚动数组)

  上面的求解1的空间复杂度时O(N)。
在这里插入图片描述
  通过上图我们容易看出来,每次求解的时候,我们只需要知道前面的三个值即可,但是求解1中我们使用了一个数组,这就浪费了我们得空间,我们优化就可以从这方面入手。
  定义四个变量,前三个变量表示dp[i-1], dp[i-2],dp[i-3]。第四个变量表示前三个变量相加的值,也就是dp[i]。每次需要求解下一个值的时候,就平移这前三个变量。

class Solution {
public:
    int tribonacci(int n) {
        // 1.创建dp表
        // 2.初始化
        int a = 0, b = 1, c = 1, d = 2;
        
        // 解决边界问题
        if(0 == n) return 0;
        if(1 == n || 2 == n) return 1;

        // 3.填表
        for(int i = 3; i <= n; i++)
        {
            d = a+b+c;
            a=b, b=c, c=d;
        }

        return d;
    }
};

三步问题

三步问题

在这里插入图片描述
  我们可以尝试手动求解前面几个的解,填入dp表。
在这里插入图片描述
  当我们计算到第4个台阶的时候,我们发现可以直接到达第4个台阶的方式分别是:

  1. 从第3个台阶起,上1个台阶到达。
  2. 从第2个台阶起,上2个台阶到达。
  3. 从第1个台阶起,上3个台阶到达。

  因为小孩一次只可以上1阶、2阶或3阶,所以只有这3种方式可以直接到达第4个台阶。
则我们经过第3个台阶到达第4个台阶的方式数有4种。
   经过第2个台阶到达第4个台阶的方式数有2种。
   经过第1个台阶到达第4个台阶的方式数有1种。
将三种方式相加,就是总的到达第4个台阶的方式数7种。
  按照这个方法往下求解,发现依旧适用。

于是简化理解,
       状态表示为:dp[i]表示到达第i个台阶的方式数量。
     状态转移方程为:dp[i] = dp[i-1]+dp[i-2]+dp[i-3];
        初始化为:dp[1] = 1, dp[2] = 2, dp[3] = 4;

求解1

class Solution {
public:
    int waysToStep(int n) {
        // 解决边界问题
        if(1 == n || 2 == n) return n;
        if(3 == n) return 4;
        
        // 1.创建dp表
        vector<int> dp(n+1);

        // 2. 初始化
        dp[1] = 1, dp[2] = 2, dp[3] = 4;
        
        // 3. 填表
        for(int i = 4; i <= n; i++)
        {
            dp[i] = ((dp[i-1]+dp[i-2])%1000000007+dp[i-3])%1000000007;
        }

        return dp[n] ;
    }
};

求解2(滚动数组)

class Solution {
public:
    int waysToStep(int n) {
        // 解决边界问题
        if(1 == n || 2 == n) return n;
        if(3 == n) return 4;
        
        // 1.创建dp表
        // 2. 初始化
        int a = 1, b = 2, c = 4, d = 0;
        
        // 3. 填表
        for(int i = 4; i <= n; i++)
        {
            d = ((a+b)%1000000007+c)%1000000007;
            a=b, b=c, c=d;
        }

        return d ;
    }
};

     😄 创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看😄

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JSON简介以及如何在Python中使用JSON

什么是JSON&#xff1f; JSON是"JavaScript Object Notation"的简称&#xff0c;是一种数据交换格式 JSON格式 假设我们有一个对象&#xff0c;这个对象有两个属性&#xff1a;“name”跟“age”。 在JSON中是这样表达的&#xff1a; { "name":"男孩…

【 C++ 】闭散列哈希表的模拟实现

哈希节点状态 我们都很清楚数组里的每一个值无非三种状态&#xff1a; 如果某下标没有值&#xff0c;则代表空EMPTY。如果有值在代表存在EXIST。如果此位置的值被删掉了&#xff0c;则表示为DELETE。 而这三种状态我们可以借助enum枚举来帮助我们表示数组里每个位置的状态。…

RK3568平台开发系列讲解(基础篇)如何快速学习一套 Linux开发板源码

🚀返回专栏总目录 文章目录 一、基础代码二、驱动代码沉淀、分享、成长,让自己和他人都能有所收获!😄 拿到一份源码和一块评估板,如何快速找到与这块板相关的源码,是很多研发人员都曾遇到过的问题。如果对内核源码结构有大概了解,要完成这些事情也不难,通常可按照基础…

ASLR 和 PIE

前言 ASLR&#xff08;Address Space Layout Randomization&#xff0c;地址空间随机化&#xff09;是一种内存攻击缓解技术&#xff0c;是一种操作系统用来抵御缓冲区溢出攻击的内存保护机制。这种技术使得系统上运行的进程的内存地址无法被预测&#xff0c;使得与这些进程有…

高性能 Kafka 及常见面试题

Kafka 是一种分布式的&#xff0c;基于发布/订阅的消息系统&#xff0c;原本开发自 LinkedIn&#xff0c;用作 LinkedIn 的事件流&#xff08;Event Stream&#xff09;和运营数据处理管道&#xff08;Pipeline&#xff09;的基础。 基础原理详解可见 Kafka 基本架构及原理 基础…

事件循环解析

浏览器的进程模型 何为进程&#xff1f; 程序运行需要有它自己专属的内存空间&#xff0c;可以把这块内存空间简单的理解为进程 每个应用至少有一个进程&#xff0c;进程之间相互独立&#xff0c;即使要通信&#xff0c;也需要双方同意。 何为线程&#xff1f; 有了进程后&…

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

Java根据excel模版导出Excel&#xff08;easyexcel、poi&#xff09;——含项目测试例子拿来即用 1. 前言1.1 关于Excel的一般导出2.2 关于easyexcel的根据模版导出 2. 先看效果2.1 模版2.2 效果 3. 代码实现&#xff08;核心代码&#xff09;3.1 项目代码结构3.2 静态填充例子…

全域增长方法论:帮助品牌实现科学经营,助力长效生意增长

前两年由于疫情反复、供给需求收缩等条件制约&#xff0c;品牌业务均受到不同程度的影响。以双十一和618电商大促为例&#xff0c;就相比往年颇显“惨淡”&#xff0c;大多品牌营销都无法达到理想预期。 随着市场环境不断开放&#xff0c;2023年营销行业开始从低迷期走上了高速…

RPA中国 x UiPath | 第六届RPA极客挑战赛,3月16日上海开赛!

随着人工智能技术的不断进步以及数字化转型的深入&#xff0c;企业对于高效、精准、自动化的业务流程需求日益迫切。RPA技术作为连接人类工作与机器操作的桥梁&#xff0c;正逐渐从规则驱动发展为智能决策的助手。 由RPA中国联合UiPath共同主办的【第六届RPA极客挑战赛】将于2…

高性能API云原生网关 APISIX安装与配置指南

Apache APISIX是Apache软件基金会下的顶级项目&#xff0c;由API7.ai开发并捐赠。它是一个高性能的云原生API网关&#xff0c;具有动态、实时等特点。 APISIX网关可作为所有业务的流量入口&#xff0c;为用户提供了丰富的功能&#xff0c;包括动态路由、动态上游、动态证书、A…

【LeetCode每日一题】938. 二叉搜索树的范围和

2024-2-26 文章目录 [938. 二叉搜索树的范围和](https://leetcode.cn/problems/range-sum-of-bst/)思路&#xff1a;写法一&#xff1a;在中间累加写法二&#xff1a;在最后累加 938. 二叉搜索树的范围和 思路&#xff1a; 1.在二叉搜索树中&#xff1a;左子树的结点都小于根节…

【Excel PDF 系列】POI + iText 库实现 Excel 转换 PDF

你知道的越多&#xff0c;你不知道的越多 点赞再看&#xff0c;养成习惯 如果您有疑问或者见解&#xff0c;欢迎指教&#xff1a; 企鹅&#xff1a;869192208 文章目录 前言转换前后效果引入 pom 配置代码实现 前言 最近遇到生成 Excel 并转 pdf 的需求&#xff0c;磕磕碰碰总…

UE5 C++ Widget练习 Button 和 ProgressBar创建血条

一. 1.C创建一个继承Widget类的子类&#xff0c; 命名为MyUserWidget 2.加上Button 和 UserWidget的头文件 #include "CoreMinimal.h" #include "Components/Button.h" #include "Blueprint/UserWidget.h" #include "MyUserWidget.genera…

2步破解官方sublime4

sublime简要破解流程 1.下载sublime官方最新版2. 破解流程 1.下载sublime官方最新版 打开 官方网站下载 portable version 版&#xff0c;省的安装。。解压到任意位置&#xff0c;备份 sublime_text.exe 文件 2. 破解流程 打开网址把文件 sublime_text.exe 拖入网页搜索替换…

飞书公式留存

飞书公式留存 if(and(month([完成日期])>7,month([完成日期])<9),"Q3季度"&#xff0c;if(and(month([完成日期])>10,month([完成日期])<12),"Q4季度"&#xff0c;""))

基于YOLOv5+PySide6的火灾火情火焰检测系统设计深度学习

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;225火灾 获取完整源码源文件已标注的数据集&#xff08;1553张&#xff09;配置跑起来说明 可有偿49yuan一对一远程操作&#xff0c;在你电脑跑起来 效果展示&#xff1a; ​数据集在下载的文件夹&#xff1a;yolov5-5.0\…

抽象的后端

Connection refused: no further information 出现这条代码的核心是你使用redis&#xff0c;但是本地没有开启redis服务 如何启动redis服务 第一步&#xff1a;确定你安装了对应的框架 以spring为例 <dependency><groupId>org.springframework.boot</group…

详解POCV/SOCV的时序报告

​POCV/SOCV的时序报告中有如下变量&#xff1a; Mean: 高斯分布中的μ值&#xff08;平均值&#xff09; Sensit: sensitivity&#xff0c;也就是1个Sigma的值&#xff1b; Corner: Sigma边界的最差值 cell的delay Delay mean N * Delay sigma; cell 的Transition Sl…

十一、Qt自定义Widget组件、静态库与动态库

一、自定义Widget组件 1、自定义Widget组件 使用步骤采用提升法&#xff08;promotion&#xff09;重新定义paintEvent事件 2、实现程序 &#xff08;1&#xff09;创建项目&#xff0c;基于QWidget &#xff08;2&#xff09;添加类&#xff0c;为Widget组件提升类 #inclu…

嵌入式C语言(三)

typeof() 使用typeof可以获取一个变量或表达式的类型。 typeof的参数有两种形式&#xff1a;表达式或类型。 int i;typeof(i) j 20; --> int j 20;typeof(int *) a; -->int *a; int f(); -->typeof(f()) k;--? int k我们可以看出通过typeof获取一个变量的…