递推数列的计算

article/2025/9/14 3:44:57

利用递归函数

我们最熟悉的一个递推数列就是斐波那契数列。 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , . . . 1, 1, 2, 3, 5, 8, 13, 21, ... 1,1,2,3,5,8,13,21,...,斐波那契数列规定数列的第一个元素和第二个元素都为1,后面的元素是前两个元素之和,可以利用递推公式描述如下:

F ( n ) = { 1 n = 1 o r n = 2 F ( n − 1 ) + F ( n − 2 ) n > = 3 F(n) = \begin{cases}1 & n = 1 \ or \ n = 2 \\ F(n-1) + F(n-2) & n >= 3 \end{cases} F(n)={1F(n1)+F(n2)n=1 or n=2n>=3

根据斐波那契数列的递推公式,我们可以很快写出一个递归函数来计算 F ( n ) F(n) F(n)。伪代码如下:

F(n)if n == 1 or n == 2return 1if n >= 3return F(n-1) + F(n-2)

同样,对于其他的递推数列,只要给出了递推公式,我们就能根据递推公式写出一个递归函数。例如有如下递推数列 a n {a_n} an,其中 a 1 = 1 a_1 = 1 a1=1 a 2 = 2 a_2 = 2 a2=2 a n + 2 = 3 a n − 1 − 2 a n a_{n+2} = 3a_{n-1} - 2a_n an+2=3an12an,这个递推数列的递推公式如下

F ( n ) = { 1 n = 1 2 n = 2 3 F ( n − 1 ) − 2 F ( n − 2 ) n > = 3 F(n) = \begin{cases} 1 & n = 1 \\ 2 & n = 2 \\ 3F(n-1) - 2F(n-2) & n >= 3 \end{cases} F(n)=123F(n1)2F(n2)n=1n=2n>=3

F(n)if n == 1return 1if n == 2return 2if n >= 3return 3 * F(n-1) - 2 * F(n-2)

利用递归函数求解递推数项非常简单,但是计算效率很低,时间复杂度为 O ( 2 n ) O(2^n) O(2n),存在大量的重复计算。以斐波那契数列 n = 5 n=5 n=5为例调用 F ( n ) F(n) F(n),计算 F ( 5 ) F(5) F(5)需要计算 F ( 3 ) F(3) F(3) F ( 4 ) F(4) F(4),在计算 F ( 4 ) F(4) F(4)需要计算 F ( 3 ) F(3) F(3) F ( 2 ) F(2) F(2),这里 F ( 3 ) F(3) F(3)就被重复计算了,当 n n n的值很大的时候,这个重复计算的值就非常多了。

15be339efb06b0bc.png

利用动态规划

为了避免重复计算,我们可以使用动态规划来计算递推数列,同样是以我们最熟悉的斐波那契数列为例。从第三个数开始,每一个数只依赖于前两个数,我们可以保存前两个数,在每计算一个数后,更新这两个数。伪代码如下:

F(n)if n >= 1:a = 0b = 1for i = 1 to na, b = b, a+breturn a

利用动态规划来求解递推数列相比直接使用递归函数来说优化了不少,时间复杂度为 O ( n ) O(n) O(n),其中每一个数最多只会计算一次。

利用矩阵快速幂

同样使用斐波那契数列为例子,我们把结果项构造成 1 × 2 1 \times 2 1×2的矩阵 [ F ( n ) F ( n − 1 ) ] \begin{bmatrix} F(n) & F(n-1) \end{bmatrix} [F(n)F(n1)],为了得到这个矩阵,我们可以利用初始矩阵乘以转置矩阵来获得。我们假设已经知道了初始矩阵 [ F ( n − 1 ) F ( n − 2 ) ] \begin{bmatrix} F(n-1) & F(n-2) \end{bmatrix} [F(n1)F(n2)],根据公式 [ F ( n ) F ( n − 1 ) ] = [ F ( n − 1 ) F ( n − 2 ) ] × [ a b c d ] \begin{bmatrix} F(n) & F(n-1) \end{bmatrix} = \begin{bmatrix} F(n-1) & F(n-2) \end{bmatrix} \times \begin{bmatrix} a & b \\ c & d \end{bmatrix} [F(n)F(n1)]=[F(n1)F(n2)]×[acbd],我们可以计算出转置矩阵 [ a b c d ] = [ 1 1 1 0 ] \begin{bmatrix} a & b \\ c & d \end{bmatrix} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} [acbd]=[1110]

有了转置矩阵后,我们可以直接通过矩阵运算来计算出最后的结果项。 [ F ( n ) F ( n − 1 ) ] = [ F ( n − 2 ) F ( n − 3 ) ] × [ 1 1 1 0 ] 2 \begin{bmatrix} F(n) & F(n-1) \end{bmatrix} = \begin{bmatrix} F(n-2) & F(n-3) \end{bmatrix} \times \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^2 [F(n)F(n1)]=[F(n2)F(n3)]×[1110]2,最后,我们可以直接通过初始项 [ 1 1 ] \begin{bmatrix} 1 & 1 \end{bmatrix} [11]乘以转置矩阵的 n − 2 n-2 n2次方来构造出斐波那契数列的结果项。 [ F ( n ) F ( n − 1 ) ] = [ 1 1 ] × [ 1 1 1 0 ] n − 2 \begin{bmatrix} F(n) & F(n-1) \end{bmatrix} = \begin{bmatrix} 1 & 1 \end{bmatrix} \times \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{n-2} [F(n)F(n1)]=[11]×[1110]n2

在这里,我们的置换矩阵是 2 × 2 2 \times 2 2×2是由于斐波那契数列是一个二维递推数列。通俗地讲,如果一个递推数列的任意项是可以由最原始的前 k k k个数递推出来,那么这个递推数列就是 k k k维的。斐波那契数列的任意一项都是从 F ( 1 ) , F ( 2 ) F(1),F(2) F(1)F(2)推出来的,所以斐波那契数列是二维递推数列。假设现在有一个递推数列 a 1 = 1 , a 2 = 1 , a 3 = 1 , a n + 3 = a n + a n + 2 a_1 = 1, a_2 = 1, a_3 = 1, a_{n+3} = a_{n} + a_{n+2} a1=1,a2=1,a3=1,an+3=an+an+2,这个递推数列就是三维的。所以一个 k k k维的递推数列结果项可以这样构造

[ F ( n ) . . . F ( n − k + 1 ) ] = [ F ( k ) . . . F ( 1 ) ] × [ a 11 . . . a 1 k . . . . . . . . . a k 1 . . . a k k ] n − k \begin{bmatrix} F(n) & ... & F(n-k+1) \end{bmatrix} = \begin{bmatrix} F(k) & ... & F(1) \end{bmatrix} \times \begin{bmatrix} a_{11} & ... & a_{1k} \\ ... & ... & ... \\ a_{k1} & ... & a_{kk} \end{bmatrix}^{n-k} [F(n)...F(nk+1)]=[F(k)...F(1)]×a11...ak1.........a1k...akknk

在计算转置矩阵的幂 A n A^n An的时候可以利用矩阵快速幂来计算。假设这里的 n = 8 n=8 n=8,按照常规计算方法需要进行8次矩阵乘法运算。但是我们可以通过计算 A × A A \times A A×A得到 A 2 A^2 A2,再通过 A 2 × A 2 A^2 \times A^2 A2×A2得到 A 4 A^4 A4,最后通过 A 4 × A 4 A^4 \times A^4 A4×A4得出结果,这里只需要三次矩阵乘法。所以利用矩阵快速幂可以将求解递推数列的时间代价下降到 O ( lg ⁡ n ) O(\lg n) O(lgn)


http://chatgpt.dhexx.cn/article/El5b8X1D.shtml

相关文章

极限求解--递推型数列

本文来自于公众号【考研数学直线笔记】 0 序言 递推型数列,一般可以表示为x(n1)f(x(n)),这一类题目的基本思想都是“先证明数列的极限存在,然后再求出极限值”,求极限值比较简单,设极限求等式就行了,难点在…

Autohotkey window 下宏键盘、宏命令开发入门

? ? ? ? 我的AHK下载地址:https://github.com/dragon8github/Pandora/raw/master/pandora.exe AutoHotKey 下载:https://autohotkey.com/download/ 国内自制的ahk网站:https://www.autoahk.com/ 推荐下载installer 官方网站:https://www.autohotkey.com/docs/AutoHot…

【开源项目分享】GitHub中文排行榜 - 帮助你发现高分优秀中文项目-Java

榜单设立目的 🇨🇳 GitHub中文排行榜,帮助你发现高分优秀中文项目;各位开发者伙伴可以更高效地吸收国人的优秀经验、成果;中文项目只能满足阶段性的需求,想要有进一步提升,还请多花时间学习高分…

HTML+CSS+JS+Servlet+MSQL搭建个人博客

3.应用技术:HTMLCSSJSJSPServletMSQL 前端后台管理。 4.开发环境:eclipsejdk1.8tomcat8.5 mysql5.7前端Layui。 二、前端 1.博客首页 博主和用户可以访问到博客系统的首页,首页内容主要包括导航条,文章推荐和登录注册管理模块…

用 Dev-C++ 编写简单的走迷宫小游戏

用 Dev-C 编写简单的走迷宫小游戏 前言基础版优化版 前言 以下是显示效果 B站视频讲解:【小游戏】用 Dev-C 编写简单的控制台走迷宫小游戏 【小游戏】用 Dev-C 编写简单的控制台走迷宫小游戏 基础版 用 # 代表墙 用 空格 代表空地 用 O 代表玩家 地图存储&#…

简单的迷宫问题(DFS/BFS分别求解)

简单的迷宫问题 题目描述输入样例输出样例 dfs解题思路(深搜)路线规划DFS特点C源码(DFS) bfs解题思路(广搜)路线规划测试代码段BFS特点C源码(BFS) 题目描述 现在需要你来规划一条路线,从起点到终点的最短路线。 给你一个nm的地图(…

基于JAVA的简单迷宫游戏

一、实验要求 1. 迷宫游戏是非常经典的游戏,在该题中要求随机生成一个迷宫,并求解迷宫。 2. 要求游戏支持玩家走迷宫,和系统走迷宫路径两种模式。玩家走迷宫,通过键盘方向键控制,并在行走路径上留下痕迹;系…

C++实现简单的走迷宫

c实现简单走迷宫 用n*n个小方格代表迷宫,每个方格上有一个字符0或1,0代表这个格子不能走,1代表这个格子可以走。只能一个格子一个走,而且只能从一个格子向它的上、下、左、右四个方向走,且不能重复。迷宫的入口和出口分…

迷宫问题(简单模拟)

目录导航 图解体会领悟:代码实现(Java):C语言版C版 为了复习递归,而模拟学习的。所以迷宫不大,总体是8行7列。 图解 A为起点,B为终点。 如下图在A和B之间设置挡板被隔绝之后,结果如…

超级简单的迷宫代码 初学者程序

迷宫 走迷宫一种比较有趣&#xff0c;操作简单的小游戏。 #include<stdio.h> #include<getch.h> #include<stdlib.h> #include<time.h> int main(int argc,const char*argv[]) {//构造迷宫地图char maze[10][10]{{#,#,#,#,#,#,#,#,#,#},{#,,#,#,#,#…

最简单的迷宫求解

在计算机中&#xff0c;我们可以把迷宫当做一个二维数组。其中0表示通路&#xff0c;1表示墙。 我们以下图为例&#xff0c;对于只有一条通路的简单迷宫进行求解 该迷宫存储在“Map.txt”文档中。 对于该迷宫&#xff0c;我们首先将入口点压入栈中&#xff0c;然后通过对该点…

JAVA 中实现的简单的迷宫小游戏

多的不说&#xff0c;直接上代码&#xff0c;就是一个简单的迷宫小游戏。 import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Random; import java.util.Stack; import javax.swing.JFr…

Python实现迷宫游戏

项目&#xff1a;迷宫游戏 摘要1.引言1.1研究的背景及意义1.2研究的内容 2.系统结构2.1系统的结构2.2基本思路 3.实现代码3.1Maze类3.2Player类3.3Controller类3.4主函数 4.实验5.总结和展望参考文献 摘要 本次实验设计了一款迷宫小游戏&#xff0c;采用用Python开发技术实现。…

C语言实现简单迷宫

C语言实现迷宫程序 前言 大家小时候一定都玩过迷宫这个游戏&#xff0c;很吸引人吧&#xff0c;有那种走不出来就不罢休的执着&#xff0c;然后走出来了觉得自己很强&#xff0c;自己可以了&#xff0c;接着激动的开始下一个关卡&#xff0c;慢慢的沉溺在迷宫的世界里了。 然…

如何使用C语言实现简单迷宫(递归和非递归实现 含图例)

1.非递归实现 简单迷宫&#xff1a;只有一条通路的迷宫 思路&#xff1a;在找迷宫通路的时候&#xff0c;我们往往是在给定入口(入口合法且为通路)的情况下&#xff0c;沿着入口的某个方向走&#xff08;此方向是通路&#xff09;。现给定走迷宫的方向&#xff1a;上、左、右…

简单迷宫(递归)

代码思路 1.创建二位数组作为迷宫 2.数字1为墙壁&#xff0c;2为经过的位置&#xff0c;3为死路&#xff0c;0为未探寻的位置 3,定义一个起点和终点&#xff0c;运用递归的方法&#xff0c;按照自己设计的寻找方向的优先级运行&#xff0c;直到让终点值为2则返回true&#x…

简单迷宫问题

简单迷宫问题 一、问题描述二、数据组织三、算法说明附录&#xff1a;完整代码 #简单迷宫问题 一、问题描述 给定一个MN得迷宫&#xff0c;求一条从指定入口到出口得迷宫路径。假设一个迷宫如图1所示&#xff0c;&#xff08;这里MN8)&#xff0c;其中每个方块用空白表示通道…

maven生命周期lifecycle和plugins介绍

一、Maven的生命周期 生命周期的定义&#xff1a;Maven的生命周期就是为了对所有的构建过程进行抽象和统一。在大量项目的构建过程中&#xff0c;Maven总结出了一套高度完善的&#xff0c;易于扩展的生命周期&#xff0c;包括项目的清理&#xff0c;初始化&#xff0c;编译&am…

【Maven】IDEA中Maven生命周期

Maven生命周期&#xff08;lifecycle&#xff09;由各个阶段组成&#xff0c;每个阶段由Maven的插件plugin来执行完成。 生命周期&#xff08;lifecycle&#xff09;主要包括clean、resources、complie、install、pacakge、testResources、testCompile、deploy等&#xff0c;其…