【动态规划】斐波那契数列模型 {动态规划的解题思路;动态规划的优化方案;动态规划的基础题型}

一、经验总结

动态规划题型的解题思路:

  1. 状态表示:dp[i]的含义是什么。通过解题经验和题目要求得到,一般有以下两个方向:
    • 以i位置为起点
    • 以i位置为终点
  2. 状态转移方程:dp[i]怎么求。根据距离i位置最近的一步划分问题,用之前或之后的状态推导出dp[i]的值。
  3. 初始化:为了保证填表的时候不越界,预处理边界情况
  4. 填表顺序:保证填写当前状态的时候,所需要的状态已经计算过了
  5. 返回值:题目要求+状态表示

提示:同一个动态规划问题,有时可以采用多种不同的状态表示(如2.3)。状态表示不同,其余的4点也不同。而有些问题的状态表示可能只适用于其中的一种,要因题而议选择可行的方案。

动态规划的优化方案:

  1. 空间优化:采用滚动数组的方案,只需要记录求当前状态时所需要的状态即可。
  2. 虚拟节点:设置虚拟节点,方便处理边界情况。需要注意以下两点:
    • 虚拟节点的初始值,要保证后续填表的正确性。
    • dp表与原始表的下标映射关系

二、相关编程题

2.1 第N个泰波那契数

题目链接

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

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述

编写代码

//动态规划
class Solution {
public:
    int tribonacci(int n) {
        vector<int> dp(n<=2? 3:n+1); //创建dp表
        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]; //返回值
    }
};

//空间优化
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;
        for(int i = 3; i <= n; ++i)
        {
            d = a+b+c;
            a=b, b=c, c=d; //滚动数组
        }
        return d;
    }
};

2.2 三步问题

题目链接

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

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述

编写代码

//经典动态规划
class Solution {
public:
    int waysToStep(int n) {
        const int MOD = 1e9+7;
        vector<long> dp(n<=3? 4:n+1); //创建dp表
        dp[1]=1, dp[2]=2, dp[3]=4; //初始化
        for(int i = 4; i <= n; ++i) //填表
        {
            dp[i] = dp[i-1]+dp[i-2]+dp[i-3];
            dp[i]%=MOD;
        }
        return dp[n]; //返回
    }
};

//空间优化版本
class Solution {
public:
    int waysToStep(int n) {
        if(n==1 || n==2) return n;
        if(n==3) return 4;
        const int MOD = 1e9+7;
        long a=1, b=2, c=4, d;
        for(int i = 4; i <= n; ++i)
        {
            d = a+b+c;
            d %= MOD;
            a=b, b=c, c=d; //滚动数组
        }
        return d;
    }
};

2.3 使用最小花费爬楼梯

题目链接

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述

编写代码

//解法一:以i位置为终点
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> dp(n+1); //创建dp表
        dp[0] = dp[1] = 0; //初始化
        for(int i = 2; i <= n; ++i) //填表
        {
            dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[n]; //返回值

    }
};

//解法二:以i位置为起点
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        vector<int> dp(n); //创建dp表
        dp[n-1] = cost[n-1]; //初始化
        dp[n-2] = cost[n-2];
        for(int i = n-3; i >= 0; --i) //填表
        {
            dp[i] = min(dp[i+1], dp[i+2]) + cost[i];
        }
        return min(dp[0], dp[1]); //返回值
    }
};

2.4 解码方法

题目链接

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

题目描述

在这里插入图片描述

算法原理

在这里插入图片描述

编写代码

//经典动态规划
class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();
        if(n==1) return CheckCode(s[0])? 1:0;
        vector<int> dp(n); //dp[i]表示以i位置为结尾的解码方法
        dp[0] = CheckCode(s[0])? 1:0; //初始化
        dp[1] = CheckCode(s[1])? dp[0]:0;
        dp[1] += CheckCode(s[0], s[1])? 1:0;
        for(int i = 2; i < n; ++i)
        {
            dp[i] = CheckCode(s[i])? dp[i-1]:0;
            dp[i] += CheckCode(s[i-1], s[i])? dp[i-2]:0;
        }
        return dp[n-1];
    }

    bool CheckCode(char a, char b = 0)
    {
        if(b == 0)
        {
            return a>='1' && a<='9';
        }
        else
        {
            int tmp = (a-'0')*10+b-'0';
            return tmp>=10 && tmp<=26;
        }
    }
};

//添加虚拟节点,方便处理边界问题
class Solution {
public:
    int numDecodings(string s) {
        int n = s.size();  
        vector<int> dp(n+1); //dp[i]表示以i位置为结尾的解法方法
        dp[0] = 1; //注意虚拟节点的初始值
        dp[1] = CheckCode(s[0])? 1:0; //初始化
        for(int i = 2; i <= n; ++i)
        {
            dp[i] = CheckCode(s[i-1])? dp[i-1]:0;
            dp[i] += CheckCode(s[i-2], s[i-1])? dp[i-2]:0;
        }
        return dp[n];
    }
};

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

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

相关文章

公司面试题总结(六)

31.说一说 webpack 的构建流程是什么&#xff1f; ⚫ 初始化流程&#xff1a; ◼ 从配置文件和 Shell 语句中读取与合并参数 ◼ 初始化需要使用的插件和配置插件等执行环境所需要的参数 ⚫ 编译构建流程&#xff1a; ◼ 从 Entry 发出&#xff0c;针对每个 Module 串行…

【 ClickHouse】 ClickHouse数据类型(整型、浮点型、布尔型、Decimal型、字符串、数组、时间类型)(二)

ClickHouse数据类型 整型 固定长度的整型&#xff0c;包括有符号整型或无符号整型。 1)整型范围&#xff1a; Int8 - [-128 : 127] Int16 - [-32768 : 32767] Int32 - [-2147483648 : 2147483647] Int64 - [-9223372036854775808 : 9223372036854775807]2)无符号整型范围&…

【linux】内核从tcp层调用IP层摸索中

合入代码&#xff1a; 登录 - Gitee.com 这是运行日志&#xff1a; https://gitee.com/r77683962/linux-6.9.0/raw/master/test_log/kern_tcp_ip.log 日志截取部分&#xff08;也不知道对不对&#xff0c;凭感觉走。。。。&#xff09;

关机充电动画:流程与定制

关机充电动画&#xff1a;流程与定制 基于MTK平台Android 11分析 生成logo.bin 关机充电动画是由一系列的bmp图片组成的&#xff0c;这些图片资源存在于vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo目录下&#xff08;当然不仅保护关机充电动画&#xff0c…

自动驾驶仿真:Carsim转向传动比设置

文章目录 一、转向传动比概念二、设置转向传动比1、C factor概念2、Steer Kinematics概念3、传动比计算公式 三、转向传动比验证 一、转向传动比概念 转向传动比&#xff08;Steering Ratio&#xff09;表示方向盘转动角度与车轮转动角度之间的关系。公式如下&#xff1a; 转向…

乘法与位运算

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 参考代码 描述 题目描述&#xff1a; 进行一个运算单元的电路设计&#xff0c;A[7:0]*11111011&#xff0c;尽量用最少的资源实现&#xff0c;写出对应的 RTL 代码。 信号示意&#xff1a; A信号输入 B 信号…

[自动驾驶 SoC]-4 特斯拉FSD

FSD, 参考资料来源FSD Chip - Tesla - WikiChip 另外可参考笔者之前分享文章&#xff1a;[自动驾驶技术]-6 Tesla自动驾驶方案之硬件&#xff08;AI Day 2021&#xff09;&#xff0c;​​​​​​​[自动驾驶技术]-8 Tesla自动驾驶方案之硬件&#xff08;AI Day 2022&#xf…

DGit的使用

将Remix连接到远程Git仓库 1.指定克隆的分支和深度 2.清理&#xff0c;如果您不在工作区上工作&#xff0c;请将其删除或推送至 GitHub 或 IPFS 以确保安全。 为了进行推送和拉取&#xff0c;你需要一个 PAT — 个人访问令牌 当使用 dGIT 插件在 GitHub 上推送、拉取、访问私…

Studying-代码随想录训练营day13| 二叉树理论基础、二叉树递归遍历、二叉树迭代遍历、二叉树层序遍历

第十三天&#xff0c;&#x1f4aa;(ง •_•)ง&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 二叉树理论基础 二叉树的种类&#xff1a; 二叉树的存储方式 二叉树的遍历方式 二叉树的定义&#xff1a; 二叉树递归遍历 二叉树的迭代遍历 二叉树的层次遍历 …

数据库新技术【分布式数据库】

文章目录 第一章 概述1.1 基本概念1.1.1 分布式数据库1.1.2 数据管理的透明性1.1.3 可靠性1.1.4 分布式数据库与集中式数据库的区别 1.2 体系结构1.3 全局目录1.4 关系代数1.4.1 基操1.4.2 关系表达式1.4.3 查询树 第二章 分布式数据库的设计2.1 设计策略2.2 分布设计的目标2.3…

深度学习入门5——为什么神经网络可以学习?

在理解神经网络的可学习性之前&#xff0c;需要先从数学中的导数、数值微分、偏导数、梯度等概念入手&#xff0c;从而理解为什么神经网络具备学习能力。 1.数值微分的定义 先从导数出发理解什么是梯度。某一点的导数直观理解就是在该点的切线的斜率。在数学中导数表示某个瞬…

Spring的事务步骤

一、事务处理方案&#xff1a; Spring框架中提供的事务处理方案&#xff1a;一共有两种&#xff1a; 1.适合中小项目使用的&#xff0c; 注解方案&#xff1a; 注解的方式做事务用起来简单&#xff0c;灵活&#xff0c;方便&#xff0c;中小型项目中用它比较方便&#xff0c…

白酒:酒文化的教育价值与实践

酒文化作为中国传统文化的重要组成部分&#xff0c;具有丰富的教育价值。云仓酒庄的豪迈白酒作为酒文化的品牌之一&#xff0c;在传承与发展中不断挖掘和发挥酒文化的教育价值。 首先&#xff0c;豪迈白酒有责任传承丰富的历史文化知识。从酒的起源、酿造技艺、酒器文化到酒礼酒…

Github上传大于100M的文件(ubuntu教程)

安装Git-lfs Git Large File Storage (LFS) 使用 Git 内部的文本指针替换音频样本、视频、数据集和图形等大文件&#xff0c;同时将文件内容存储在 GitHub.com 或 GitHub Enterprise 等远程服务器上。官网下载&#xff1a;https://git-lfs.github.com/ ./install.sh上传 比如…

教你如何安装 IntelliJ IDEA

安装 IntelliJ IDEA 的步骤通常如下&#xff0c;这里提供的是基于 Windows 系统的安装指南。 下载 IntelliJ IDEA 1. 访问 JetBrains 官方网站&#xff1a;[https://www.jetbrains.com/idea/download/](Download IntelliJ IDEA – The Leading Java and Kotlin IDE) 2. 选择适…

一文带你入门【论文排版】利器·LaTeX |Macos

小罗碎碎念 我在刚开始写公众号的时候&#xff0c;写过一期推文&#xff0c;详细的讲解过如何使用LaTeX快速的进行论文排版。不过当时用的是windows的系统&#xff0c;这一次把Mac端的教程补上。 windows系统教程 https://zhuanlan.zhihu.com/p/677481269 LaTeX是一种流行的排…

【UIDynamic-动力学-UICollisionBehavior-action Objective-C语言】

一、我们说,这个碰撞行为啊,collision,它里边还有一个属性,叫做action,它能够干什么,它能够实时的去监听, 1.实时的去监听,我们当前的这个view的一个frame的变化, 它会调用action的方法,实际上,action方法,它是一个block,然后呢,view的frame变化的时候,它会一直…

Keil生成bin文件

keil软件默认是只生成hex文件虽然也可以下载但是有时候要用到bin文件 只需要加入以下代码在keil软件中即可 fromelf.exe --bin -o “$LL.bin” “#L” 然后编译 输出信息&#xff0c;可以看到已经生成了bin文件

Nacos从入门到实战

一、Nacos介绍 1.什么是Nacos 官方&#xff1a;一个更易于构建云原生应用的动态服务发现&#xff08;Nacos Discovery&#xff09;、服务配置&#xff08;Nacos Config&#xff09;和服务管理平台 集 注册中心配置中心服务管理 平台 注册中心&#xff1a;把所有的服务注册进去…

第6章 设备驱动程序(3)

目录 6.5 块设备操作 6.5.1 块设备的表示 6.5.2 数据结构 6.5.3 向系统添加磁盘和分区 6.5.4 打开块设备文件 本专栏文章将有70篇左右&#xff0c;欢迎关注&#xff0c;查看后续文章。 6.5 块设备操作 特点&#xff1a; 随机访问任意位置。 固定块大小的传输。 块设备在内…