【动态规划】斐波那契模型 dp

news2024/11/23 9:10:18

在这里插入图片描述

动态规划的步骤:

  1. 状态表示。所谓状态表示就是 dp 表里的值表示什么含义,那么状态表示怎么找呢? a. 题目要求 b. 经验(以某一个位置为结尾 / 起点) + 题目要求 c. 分析问题的过程中发现重复子问题
  2. 状态转移方程。dp[ i ] 等于什么
  3. 初始化。保证填表的时候不越界
  4. 填表顺序。保证填写当前状态时,所需要的状态已经计算过了,初始化之后,下标的映射关系要一致
  5. 返回值。根据题目要求和状态表示进行返回

1. 第 N 个泰波那契数

1137. 第 N 个泰波那契数

这题比较简单,直接秒了

状态表示:dp[i] 表示第 i 个泰波那契数的值

状态转移方程: dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];

初始化:把前三个数初始化

填表顺序:从左到右

返回值:返回 dp[n]

class Solution {
    public int tribonacci(int n) {
        int[] dp = new int[38];
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 1;
        if(n < 3){
            return dp[n];
        }
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }
        return dp[n];
    }
}

还可以对上述代码进行空间优化,因为在求第 i 个位置的时候,只需要知道前三个数即可,每次求一个位置都是这样,所以就可以定义三个变量,不断地更新,实现滚动数组的效果

滚动数组空间优化版本:

class Solution {
    public int tribonacci(int n) {
        int sum = 0;
        int a = 0,b = 1,c = 1;
        if (n == 0)
            return 0;
        if (n == 1 || n == 2)
            return 1;
        for (int i = 3; i <= n; i++) {
            sum = a + b + c;
            a = b;
            b = c;
            c = sum;
        }
        return sum;
    }
}

2. 面试题 08.01. 三步问题

面试题 08.01. 三步问题

状态表示:dp[i] 表示到达第 i 个位置时的方案数

状态转移方程: dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];

初始化:计算前三个数的方案数,把前三个数初始化

填表顺序:从左到右

返回值:返回 dp[n]

class Solution {
    public int waysToStep(int n) {
        long a = 1,b = 2,c = 4;
        if(n == 1) return 1;
        if(n == 2) return 2;
        if(n == 3) return 4;
        long res = 0;
        for(int i = 4;i <= n;i++){
            res = (a + b + c) % 1000000007;
            a = b;
            b = c;
            c = res;
        }
        return (int) res;
    }
}

3. 使用最小花费爬楼梯

746. 使用最小花费爬楼梯

状态表示:dp[i] 表示到达第 i 个位置时的最小花费

状态转移方程:

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

初始化:由于需要用到前两个数,所以需要把 dp[0] 和 dp[1] 初始化,因为刚开始可以直接从 0 下标或 1 下标出发,所以可以初始化为 0

填表顺序:从左到右

返回值:返回 dp[n],楼梯顶部为 n 下标,也就是

Math.min(dp[n - 1] + cost[n - 1], dp[n - 2] + cost[n - 2])

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n];
        if (n == 1 ) return 0;
        if(n == 2) return Math.min(cost[0],cost[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 Math.min(dp[n - 1] + cost[n - 1], dp[n - 2] + cost[n - 2]);
    }
}

还有第二种状态表示可以解决:

dp[i] 表示从 i 位置出发,到达楼顶的最小花费

初始化:用这种方法的话,就需要用到后面两个元素,所以刚开始初始化需要把最后的两个元素初始化

初始 dp[n - 1] 时就表示从 n - 1 位置支付 cost[n - 1] 就可以直接到达楼顶,dp[n - 2] 时支付 cost[n - 2] 也可以直接到达楼顶

填表顺序:从后往前

最后的返回值也就是 dp[0] 和 dp[1] 的最小值

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n];
        if (n == 1 ) return 0;
        if(n == 2) return Math.min(cost[0],cost[1]);
        dp[n - 1] = cost[n - 1];
        dp[n - 2] = cost[n - 2];
        for(int i = n - 3;i >= 0;i--){
            dp[i] = Math.min(dp[i + 1] + cost[i],dp[i + 2] + cost[i]);
        }
        return Math.min(dp[0],dp[1]);
    }
}

4. 解码方法

91. 解码方法

只有在 1 ~ 26 范围内的数字才可以解码,有前导 0 或者超过 26 的都不能解码

状态表示:以 i 位置为结尾时,解码方法的总数

此时就会有两种状态,s[i] 位置单独解码,s[i] 和 s[i - 1] 结合解码,每一种状态又可以分为解码成功和解码失败两种情况

状态转移方程:(根据最近的一步划分问题)根据情况来判断 dp[i] 是否加上 dp[i - 1] 和 dp[i - 2]

初始化:初始化 dp[0] 的时候也是有两种情况的,解码成功就是 1,解码失败就是 0,初始化 dp[1] 的时候就有三种情况了,由于是两个数字,所以就需要考虑两个单独解码和结合起来解码,如果都解码失败就是 0,如果单独解码成功就加 1,如果结合起来解码又成功了就再加上 1

填表顺序:从左往右

返回值:返回 dp[n - 1]

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

上面的代码的初始化过程看起来很麻烦,还可以优化一下:

上面初始化时是 dp[1] 比较麻烦的,可以把 dp 数组多开一个元素,

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

在这里插入图片描述

 

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

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

相关文章

ChatGPT Canvas:系统提示词泄漏了~

OpenAI 推出了一款叫做 Canvas 的新工具&#xff0c;用来帮助用户更好地与 ChatGPT 协作写作和编程。详细介绍可以看这篇文章&#xff1a;ChatGPT Canvas&#xff1a;交互式对话编辑器-CSDN博客​编辑 以下是 OpenAI 新功能 “Canvas” 的系统提示内容 你是 ChatGPT&#xff0…

基于连续小波变换(CWT)批量生成一维信号的时频图 最终生成30张时频图。生成的图像可用于后续的深度学习分类或其他处理。附详细的说明文档。

Matlab基于连续小波变换&#xff08;CWT&#xff09;&#xff0c;将一维信号批量生成时频图的源代码。此示例中&#xff0c;原始信号data是30*1280的格式&#xff0c;一共30条信号&#xff0c;信号长度为1280。最终生成30张时频图。生成的图像可用于后续的深度学习分类或其他处…

SpringBoot开发——SpringSecurity安全框架17个业务场景案例(二)

文章目录 一、Spring Security 常用应用场景介绍二、Spring Security场景案例6、CSRF 保护(CSRF Protection)6.1 Spring Security 配置6.2 业务逻辑代码7、密码编码(Password Encoding)7.1 Spring Security 配置7.2 业务逻辑代码7.3 控制器8、方法级安全性(Method Securit…

Vue2电商项目(八) 完结撒花:图片懒加载、路由懒加载、打包的map文件

一、图片懒加载 安装&#xff1a;npm i vue-lazyload1.3 -s &#xff08;弹幕建议按1.3版本&#xff09; 引入 // 引入懒加载的图片 import hlw from /assets/hulu.jpg // 引入插件 import VueLazyload from vue-lazyload // 引入插件 Vue.use(VueLazyload, {// 懒加载默认的图…

Oracle登录报错-ORA-01017: invalid username/password;logon denied

接上文&#xff1a;Oracle创建用户报错-ORA-65096: invalid common user or role name 我以为 按照上文在PDB里创建了用户&#xff0c;我以为就可以用PLSQL远程连接了&#xff0c;远程服务器上也安装了对应版本的Oracle客户端&#xff0c;但是我想多了&#xff0c;客户只是新建…

【爬虫】网站反debugger、内存爆破以及网站限制开发者工具

【爬虫】网站反debugger、内存爆破以及网站直接限制开发者工具 声明&#xff1a;本文中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0…

JWT集成Keycloak

一、直接使用现有域账号、密码获取token方式 1.KeyClack 使用现有配置 Client id : account-console 2.服务配置文件配置 3.API接口配置 4. 获取token 5.调用方式&#xff08;Swagger&#xff09;(代码方式直接在请求头加上token) 5.1 配置在Swagger访问 5.2 访问需要认证的接…

JavaWeb——Vue路由(概述、介绍、使用、解决bug)

目录 概述 介绍 使用 解决bug 概述 员工管理的页面已经制作完成。其他页面的制作方式一致。 项目中准备了部门管理的页面组件 DeptView &#xff0c;这样就有了员工管理和部门管理两个页面组件。 在系统中&#xff0c;要实现点击部门管理菜单展示部门管理组件&#xff0c…

为什么Java不支持多重继承?

不支持多重继承主要是因为会产生“菱形继承”&#xff0c;也称为钻石继承的问题。 那什么是菱形继承呢&#xff1f; 它涉及到一个类继承两个父类&#xff0c;而这两个父类又继承自同一个祖先类。这种结构在没有适当处理的情况下&#xff0c;会导致继承层次中的歧义和冗余。 如…

关于BSV区块链覆盖网络的常见问题解答(下篇)

​​发表时间&#xff1a;2024年9月20日 在BSV区块链上的覆盖网络服务为寻求可扩展、安全、高效交易处理解决方案的开发者和企业家开辟了新的视野。 作为开创性的曼达拉升级的一部分&#xff0c;覆盖网络服务提供了一个强大的框架&#xff0c;用于管理特定类型的交易和数据访问…

【目标检测】室内地板砖铺设缺陷检测数据集2000张VOC+YOLO格式

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2002 标注数量(xml文件个数)&#xff1a;2002 标注数量(txt文件个数)&#xff1a;2002 标注…

图论大总结

图论基础 98. 所有可达路径 result [] path [] def dfs(graph,x,n):if x n:result.append(path[:])returnfor i in range(1,n1):if graph[x][i] 1:path.append(i)dfs(graph,i,n)path.pop() def main():n,m map(int,input().split())# 邻接矩阵graph [[0]*(n1) for _ in …

【EXCEL数据处理】000021 案例 保姆级教程,附多个操作案例。EXCEL文档安全性设置。

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】000021 案例 保姆级教程&#xff0c;附多个操作案例。…

C#高级编程笔记--字符串和正则表达式

本章的主要内容如下&#xff1a; 创建字符串 格式化表达式 正则表达式​​​​​​​ 1.1 System.String类 System.String是一个类&#xff0c;专门用于存储字符串&#xff0c;允许对字符串进行许多操作。由于这种数据类型非常重要&#xff0c;C#提供了它自己…

【C++堆(优先队列)】2233. K 次增加后的最大乘积|1685

本文涉及知识点 C堆(优先队列) 贪心&#xff08;决策包容性) LeetCode 2233. K 次增加后的最大乘积 给你一个非负整数数组 nums 和一个整数 k 。每次操作&#xff0c;你可以选择 nums 中 任一 元素并将它 增加 1 。 请你返回 至多 k 次操作后&#xff0c;能得到的 nums的 最…

用Python实现运筹学——Day 15: 线性规划的项目实战

一、学习内容 在本节中&#xff0c;我们将综合应用之前学习的线性规划知识&#xff0c;解决一个复杂的实际问题。通过这个实战项目&#xff0c;进一步理解线性规划在资源分配问题中的应用。 二、实战案例&#xff1a;公司资源分配问题 2.1 问题描述&#xff1a; 某公司生产两…

Conda答疑

文章目录 优雅的使用Conda管理python环境1. conda info -e 和conda env list区别2.conda创建环境 创建的新环境在哪个文件夹下3. 自定义路径4. anaconda 新建环境 包是来自哪里4.1. 默认 Anaconda 仓库4.2. Conda-Forge4.3. 镜像源4.4. 自定义频道4.5. 总结 5. conda config --…

Spring Boot:打造下一代医院管理系统

3系统分析 3.1可行性分析 通过对本医院管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本医院管理系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

electron打包报错-winCodeSign无法下载

electron打包报错-winCodeSign下载问题 问题描述 downloaded urlhttps://registry.npmmirror.com/-/binary/electron-builder-binaries/winCodeSign-2.6.0/winCodeSign-2.6.0.7z duration1.577s⨯ cannot execute causeexit status 2outerrorOutERROR: Cannot create s…

C++ | Leetcode C++题解之第463题岛屿的周长

题目&#xff1a; 题解&#xff1a; class Solution {constexpr static int dx[4] {0, 1, 0, -1};constexpr static int dy[4] {1, 0, -1, 0}; public:int dfs(int x, int y, vector<vector<int>> &grid, int n, int m) {if (x < 0 || x > n || y <…