动态规划---斐波那契数列模型

news/2024/10/21 11:27:30/

目录

一、斐波那契数列的基本概念

二、动态规划在斐波那契数列中的应用与优势

三、实际案例:使用动态规划解决斐波那契数列问题

四、动态规划问题的做题步骤

五、例题

1、第N个泰波那契数---点击跳转题目

2、三步问题----点击跳转题目

3、最小花费爬楼梯----点击跳转题目

4、解码方法----点击跳转题目


本文通过对斐波那契数列问题引入动态规划,这也是动态规划问题中比较简单的一类问题,通过这个模型我们一起来学习什么是动态规划算法并且动态规划问题的基本做题步骤是什么

一、斐波那契数列的基本概念

斐波那契数列是这样一个数列:从第三项开始,每一项都等于前两项之和。数列的前几项为:0, 1, 1, 2, 3, 5, 8, 13, 21, ...。这个数列的特性使得它在很多实际问题中都有着重要的应用。

二、动态规划在斐波那契数列中的应用与优势

在计算斐波那契数列时,我们可以使用递归的方式。然而,递归方式在计算较大的斐波那契数时,会存在大量的重复计算,效率非常低。而动态规划技术可以有效地避免这种重复计算,显著提高计算效率。

动态规划的基本思想是将问题分解为若干个子问题,并将这些子问题的解保存起来,以便在计算新的子问题时能够直接利用之前的结果,避免重复计算。在斐波那契数列问题中,我们可以使用动态规划技术,从下往上计算斐波那契数列,并将每个计算结果保存起来,这样在计算较大的斐波那契数时,就可以直接使用之前保存的结果,通过空间换时间的操作,大大提高了计算效率。

三、实际案例:使用动态规划解决斐波那契数列问题

下面是一个C++代码示例,展示了如何使用动态规划来计算斐波那契数列:

#include<iostream>const int N = 100;
int dp[N];int main()
{dp[0] = 1,dp[1] = 1;int n;cin>>n;for(int i=2;i<=n;i++)dp[i] = dp[i-1] + dp[i-1];cout<<dp[n]<<endl;return 0;
}

在上述代码中,我们创建了一个列表dp来保存斐波那契数列的值。初始时,列表的前两个元素被设置为斐波那契数列的前两项。然后,我们通过一个循环,从第三项开始,依次计算斐波那契数列的每一项,并将结果保存在dp列表中。最后,返回dp[n],即第n项斐波那契数的值。

动态规划在斐波那契数列中的核心思想是通过保存子问题的解来避免重复计算。具体方法是将问题分解为子问题,并按照某种顺序(如上述示例中的从下往上)依次解决这些子问题,同时保存每个子问题的解。在计算新的子问题时,如果其解已经保存,则直接利用保存的解,否则通过解决更小的子问题来得到其解,并将解保存起来。

四、动态规划问题的做题步骤

在分析题目时分为五步:

  • 状态表示:根据 经验 + 题目要求 得出

dp[i]代表什么? 一般可以 以i为结尾 以i为起点 做状态表示

  • 状态转移方程:根据dp[i]的最近一步推导得出关于dp[i]的递推公式
  • 初始化:根据递推公式来初始化需要先用到的dp值
  • 填表顺序:根据递推公式来判断填表顺序
  • 返回值:题目要求

在编写代码时分为四步:

  • 创建dp表
  • 初始化
  • 填表
  • 返回值

五、例题

1、第N个泰波那契数---点击跳转题目

本题很简单明了,题目里面就已经给出了状态转移方程,由此,我们定义dp[n]是第n个泰波斐契数

代码:

class Solution {
public:int m = 40;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、三步问题----点击跳转题目

分析:

  • 状态表示:以i为结尾分析,dp[i]为到第i个台阶的方法总数
  • 状态转移方程:分析最近一步,由于一次可以跨1到3个台阶,所以到第i个台阶的最近一步就是先到i-1、i-2、i-3这三个台阶,再分别跨1、2、3个台阶到达第i个台阶,那么从i-1层到i层这种方式到i层的方法数就是到i-1层的方法数,以此类推:dp[i] = dp[i-1]+dp[i-2]+dp[i-3]; 可以看出递推公式和上一题一摸一样,只不过这个需要我们根据题意和经验自己推导。
  • 初始化:把上1、2、3层的台阶方法数先初始化,因为递推公式要用到三个数,根据题意,dp[1] = 1,dp[2] = 2,dp[3] = 4;
  • 填表顺序:由于递推公式是由小推大,所以从左向右填表
  • 返回值:根据题意,返回dp[n] 对1000000007取模的结果即可

代码:

class Solution {
public:int waysToStep(int n) {int MOD = 1e9 + 7;//创建dp表vector<int> dp(10+n);//初始化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];}
};

题意是结果取模即可,但是因为数值过大,计算过程中就会爆数据范围,所以只能每做一次加法取一次模,和对结果取模等价; 注意,取模运算具有分配律:(A+B)%C = A%C + B%C

3、最小花费爬楼梯----点击跳转题目

分析:题中表示,从第i层向上爬,需要花费cost[i]的体力值,可以从0、1层向上爬,也就死选择到0/1层并不花费体力值;

  • 状态表示:以i为结尾,dp[i]:到第i层花费的最小体力值
  • 状态转移方程:由dp[i]最近一步推导,由于一次可以爬1~2步,到第i层之前,要么在i-1层,要么在i-2层,分类讨论,从i-1层到i层的最小花费为:dp[i-1]+cost[i-1];从i-2层到i层的最小花费为:dp[i-2]+cost[i-2],一共这两种情况,哪一种才是到达i层的最小花费呢?两者取个最小值即可:dp[i] = min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2])
  • 初始化:由递推公式可知需要前两个dp值,由题意,选择上0或1层台阶不花费体力值,dp[0] = dp[1] = 0
  • 填表顺序:由递推公式是在小推大,所以我们从左向右填表
  • 返回值:根据题意,返回dp[n]就是到达第n层台阶的最小花费

代码:

class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {int n = cost.size();vector<int> dp(10+n);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为结尾分析,做题步骤中不是还有以i为起点分析吗?其实都可以,做题的时候觉得怎样更方便就选择怎样,那么这道题我们也以i为起点来举例分析一下

  • 状态表示:以i为起点,dp[i]表示以i为起点到楼顶的最小花费
  • 状态转移方程:分析dp[i]最近的一步,以i为起点,自然只能向后看,最近的一步就是i+1层台阶和i+2层台阶; dp[i] = cost[i] + min(dp[i+1],dp[i+2])
  • 初始化:由递推公式可知,是要先直到后面的值推导前面的值,dp[n] = 0, dp[n-1] = cost[i-1]
  • 填表顺序:由递推公式,是大推小,所以是从右往左填表
  • 返回值:根据题意,要求的是从0层或1层到n层的最小花费,所以结果为min(dp[0],dp[1])

代码:

class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {   //dp[i]:以i位置出发到达楼顶的最小花费//dp[i] = min(dp[i+1]+cost[i],dp[i+2]+cost[i]);int n = cost.size();vector<int> dp(n+10);dp[n] = 0;dp[n-1] = cost[n-1];for(int i=n-2;i>=0;i--)dp[i] = cost[i] + min(dp[i+1],dp[i+2]);return min(dp[0],dp[1]);}
};

这道题怎么分析都可以,建议两种视角都看一遍加深理解

4、解码方法----点击跳转题目

分析:一个字符要么单独解码,要么合并另一个字符解码,合并时前导0情况表示解码失败

  • 状态表示:以i为结尾,dp[i]表示以i为结尾时的解码方法总数
  • 状态转移方程:根据dp[i]最近的一步,就是以i位置的字符单独解码或者i和i-1的字符合并解码两种情况,其中每种情况都要判断其合法性,是否能解码成功,解码失败则表示i位置这种情况下的解码方法数是0,如果两种情况都解码成功,dp[i] = dp[i-1] + dp[i-2]

  • 初始化:初始化0,1即可,根据是否能解码成功来分类

  • 填表顺序:从左往右
  • 返回值:dp[s.size()]

代码:

class Solution {
public:int numDecodings(string s) {int n = s.size();vector<int> dp(10+n);if(s[0]-'0' != 0) dp[0] = 1;else dp[0] = 0;if(s[0]-'0' && s[1]-'0') dp[1]++;int t = (s[0]-'0')*10 + s[1] - '0';if(t>=10 && t<= 26) dp[1]++;for(int i=2;i<n;i++){if(s[i] != '0') dp[i] += dp[i-1];int t = (s[i-1] - '0')*10 + s[i] - '0';if(10<=t && t<=26) dp[i] += dp[i-2];}return dp[n-1];}
};


http://www.ppmy.cn/news/1435705.html

相关文章

文件摆渡:安全、高效的摆渡系统助力提升效率

很多组织和企业都会通过网络隔离的方式来保护内部的数据&#xff0c;网络隔离可以是物理隔离&#xff0c;也可以是逻辑隔离&#xff0c;如使用防火墙、VPN、DMZ等技术手段来实现&#xff0c;隔离之后还会去寻找文件摆渡方式&#xff0c;来保障日常的业务和经营需求。 进行网络隔…

【数据结构】串(String)

文章目录 基本概念顺序存储结构比较当前串与串s的大小取子串插入删除其他构造函数拷贝构造函数扩大数组空间。重载重载重载重载[]重载>>重载<< 链式存储结构链式存储结构链块存储结构 模式匹配朴素的模式匹配算法(BF算法)KMP算法字符串的前缀、后缀和部分匹配值nex…

C++ | Leetcode C++题解之第48题旋转图像

题目&#xff1a; 题解&#xff1a; class Solution { public:void rotate(vector<vector<int>>& matrix) {int n matrix.size();// 水平翻转for (int i 0; i < n / 2; i) {for (int j 0; j < n; j) {swap(matrix[i][j], matrix[n - i - 1][j]);}}//…

【24届数字IC秋招总结】正式批面试经验汇总9——飞腾

文章目录 一、飞腾-IC验证工程师1.1 面试问题&#xff08;验证部&#xff09;1.2 面试问题&#xff08;处理器核&#xff09; 一、飞腾-IC验证工程师 面试时间&#xff1a;9.27 1.1 面试问题&#xff08;验证部&#xff09; 1、自我介绍 2、实习做什么 3、AHB协议的内容 4、…

DHCP的原理与配置

一.了解DHCP服务 1. DHCP (Dynamic Host Configuration Protocol)动态主机配置协议 是由Internet工作小组设计开发的&#xff0c;专门用于为TCP/IP网络中的计算机自动分配TCP/IP参数的协议 DHCP协议采用的是UDP作为传输协议&#xff0c;是给网络内的客户机自动分配IP地址&…

鸿蒙开发实例:【配置OpenHarmony SDK】

配置OpenHarmony SDK 在设置OpenHarmony应用开发环境时&#xff0c;需要开发者在DevEco Studio中配置对应的SDK信息。 说明&#xff1a; 请注意&#xff0c;OpenHarmony SDK版本精简了部分工具链&#xff0c;因此不适用于HarmonyOS应用开发。 前提条件 已下载并安装好DevEco …

推荐3个视频转文字的工具

如果是长视频转文字的话&#xff0c;我会推荐你三个专业的能够将视频文字提取出来的工具&#xff0c;操作无门槛&#xff0c;转换出的文字准确率高&#xff0c;可以直接导出文字。 1.一键识别王 https://www.xunjiepdf.com/yijianshibiewang 专业的图片文字识别软件&#xff0…

企业微信hook接口协议,根据手机号搜索联系人

根据手机号搜索联系人 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信 请求示例 {"uuid":"3240fde0-45e2-48c0-90e8-cb098d0ebe43","phoneNumber":"1357xxxx" } 返回示例 {"data&q…