题目:斐波那契数列,又称黄金分割数列(F(n+1)/F(n)的极限是1:1.618,即黄金分割率),指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……。在数学上,斐波纳契数列以如下被以递归的方法定义:

F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)

递归实现——自上而下

在很多C语言教科书中讲到递归函数的时候,都会用Fibonacci作为例子。因此很多程序员对这道题的递归解法非常熟悉,看到题目就能写出如下递归求解的代码:

long Fibonacci(long n) //递归算法

{

if(n<=) return n; //终止递归的条件

else return Fibonacci(n-) + Fibonacci(n-);//递归步骤

}

但是,教科书上反复用这个题目来讲解递归函数,并不能说明递归解法最适合这道题目。我们以求解F(10)作为例子来分析递归求解的过程。要求得F(10),需要求得F(9)和F(8)。同样,要求得F(9),要先求得F(8)和F(7)……我们用下面的树形结构来表示这种依赖关系

F(10)

/             \

F(9)          F(8)

/     \           /    \

F(8)    F(7)   F(7)   F(6)

/    \      /    \

F(7)  F(6) F(6)  F(5)

我们不难发现在这棵树中有很多结点会重复的,而且重复的结点数会随着n的增大而急剧增加。这意味这计算量会随着n的增大而急剧增大。例如,在递归计算F(10)时,F(3)的值被计算了21次。而在递归计算F(30),这个调用的次数是骇人的317811次!这些个计算实际上只有一次是必要的,其余的纯属浪费!

事实上这个递归算法的时间复杂度是指数级Ω(φn),φ=1.618(1:1.618=0.618称为黄金分割率)。

迭代算法——自底向上

下面的程序使用一个简单循环迭代来代替递归,这个非递归的形式不如上文给出的递归简单,也不太符合Fibonacci的递归定义,但是,它的运行速度提高了特别多!

迭代算法的源码如下:

// 计算斐波那契数列的非递归算法(迭代)

long Fibonacci(long n)

{

if(n<=) return n; // Fib(0)或Fib(1)的情况

long FibCurrent, FibTwoBack = , FibOneBack = ; // 用数组保存程序更简洁,但不能明显的看出迭代的思想

for(int i= ; i<=n ; i++) // n≥2的情况

{

FibCurrent = FibOneBack + FibTwoBack; // 计算Fib(i)=Fib(i-1)+Fib(i-2)

/* 下面的保存顺序不能对调 */

FibTwoBack = FibOneBack; // 保存Fib(i-1)作为下趟的Fib(i-2)

FibOneBack = FibCurrent; // 保存Fib(i)作为下趟的Fib(i-1)

}

return FibCurrent;

}

显然,这个算法的时间复杂度为O(n),相比于前面指数级的递归算法,有了质的飞跃。

事实上,这还不是最快的算法。还有一种时间复杂度是O(logn)的方法

转化为特征矩阵乘方——分治策略 + 矩阵快速幂

由数学归纳法易证:

问题转化为求

,继而就求出了F(n)。

对于乘方问题我们利用分治策略优化有

运行时间递归式:T(n) = T(n/2) + θ(1) (同二分搜索一样)    用主方法接得T(n) = θ(logn)

利用对特征矩阵乘方优化的方法可以得到最小的运行时间复杂度O(logn),代码如下:

class Matrix // 自定义2×2矩阵类

{

public:

unsigned int a11, a12, a21, a22; // 矩阵元素

Matrix(int a, int b, int c, int d) :a11(a), a12(b), a21(c), a22(d) {}// 构造函数

Matrix operator*(const Matrix &other) // 重载矩阵的乘法

{

Matrix result(, , , );

result.a11 = a11*other.a11 + a12*other.a21;

result.a12 = a11*other.a12 + a12*other.a22;

result.a21 = a21*other.a11 + a22*other.a21;

result.a22 = a21*other.a12 + a22*other.a22;

return result;

}

};

Matrix MatrixPow(const Matrix &A, unsigned int n)// 计算矩阵A的n次方(分治策略,此处自底向上迭代)

{

Matrix result(, , , ); // 单位矩阵

Matrix tmp = A;

while (n)

{

if (n & ) // &为按位"与"运算,如果n为奇数

result = result * tmp;// 单乘一次矩阵

tmp = tmp * tmp;

n = n >> ; // n右移一位,相当于n/2(向下取整)

}

return result;

}

unsigned int Fibonacci(int n)

{

if (n <= )

return n;

Matrix A(, , , ); // 特征矩阵

Matrix result = MatrixPow(A, n); // 计算矩阵A的n次方

return result.a12; // Fn即为结果矩阵中第一行第二例上的元素

}

参考资料: 《MIT算法导论公开课》第三集——分治法

《编程之美》P163

《剑指offer》P73

斐波那契&lpar;Fibonacci&rpar;数列的七种实现方法

废话不多说,直接上代码 #include "stdio.h" #include "queue" #include "math.h" usin ...

如何用Python输出一个斐波那契Fibonacci数列

a,b = 0, 1 while b<100: print (b), a, b = b, a+b

斐波那契 &lpar;Fibonacci&rpar;数列

尾递归会将本次方法的结果计算出来,直接传递给下个方法.效率很快. 一般的递归,在本次方法结果还没出来的时候,就调用了下次的递归, 而程序就要将部分的结果保存在内存中,直到后面的方法结束,再返回来计算. ...

2019&period;8&period;3 &lbrack;HZOI&rsqb;NOIP模拟测试12 A&period; 斐波那契&lpar;fibonacci&rpar;

2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

ACM&sol;ICPC 之 数论-斐波拉契●卢卡斯数列&lpar;HNNUOJ 11589&rpar;

看到这个标题,貌似很高大上的样子= =,其实这个也是大家熟悉的东西,先给大家科普一下斐波拉契数列. 斐波拉契数列 又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.… ...

递归函数练习:输出菲波拉契&lpar;Fibonacci&rpar;数列的前N项数据

/*====================================================================== 著名的菲波拉契(Fibonacci)数列,其第一项为0 ...

&lbrack;洛谷P3938&rsqb;&colon;斐波那契&lpar;fibonacci&rpar;(数学)

题目传送门 题目描述 小$C$养了一些很可爱的兔子.有一天,小$C$突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行繁衍:一对兔子从出生后第二个月起,每个月刚开始的时候都会产下一对小兔子 ...

HZOJ 斐波那契&lpar;fibonacci&rpar;

先说一个规律: 如图将每个月出生的兔子的编号写出来,可以发现一只兔子在哪一列他的父亲就是谁. 每列的首项可以通过菲波那契求得. 然后你就可以像我一样通过这个规律打表每个点的父亲,预处理出倍增数组,倍增 ...

Java Fibonacci 斐波那契亚

Java Fibonacci 斐波那契亚 /** * *

*

Copyright 1994-2018 JasonInternat ...

随机推荐

iOS 开发遇到的问题之(nil指针对NSDictionary及NSArray初始化的影响)

nil指针对NSDictionary及NSArray初始化的影响 最近在做项目的时候遇到一个挺坑的崩溃问题,是由于NSDictionary初始化时nil指针引起的崩溃.假设我们现在要初始化一个{key ...

php的Excel相关操作

1.需求 把数据库的数据输出excel格式 2.解决方案 利用phpexcel中的examples的01和07,对excel文件的读写 3.操作流程 a.https://github.com/PHPO ...

快消品销售管理系统&comma;PDA销售管理系统&comma;销售拜访PDA&comma;进销存管理PDA系统 移动扫描打印开单POS

各种ERP软件的移动订单及移动车销解决方案是针对各个需要快速.便捷的,通过智能PDA移动智能终端设备实现销售订单下达及快速车销的应用解决方案.通过将移动订单及移动车销集成到ERP的移动解决方案,可以帮 ...

mysql双主复制总结

双主复制: 1).在两台服务器上各自建立一个具有复制权限的用户: 2).修改配置文件: # 主服务器A上 [mysqld] server-id = 10 log-bin = mysql-bin rel ...

实验六 序列信号检测器的VHDL设计

一.实验目的 (1)进一步熟悉Quartus II软件和GW48-PK2S实验系统的使用方法: (2)用状态机实现序列检测器的设计,了解一般状态机的设计与应用 二.实验内容 1. 基本命题 利用Qua ...

500G JAVA视频网盘分享 &lpar;Jeecg社区&rpar;

http://blog.csdn.net/zhangdaiscott/article/details/18220411    csdn 排名400多名 500 G JAVA视频网盘分享(Jeecg社区 ...

Spring boot构建基于rest的Web服务

一.介绍:使用Spring Boot我们可以很容易的创建一个可独立运行的Rest web服务,其中内嵌tomact,我们只需“run”就可以查看效果了. Spring Boot利用Gradle或Mav ...

《Python 数据库 GUI CGI编程》

斐波那契数列在计算机的应用,斐波那契(Fibonacci)数列的几种计算机解法相关推荐

  1. python编写递归函数、求斐波那契数列第n项_用Python实现求Fibonacci数列的第n项

    1. 背景--Fabonacci数列的介绍(摘自百度百科): 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacc ...

  2. Fibonacci数列的幂和

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5237 题意:给定和,其中,,求  的值. 分析:嗯,这道题貌似有难度,如 ...

  3. fibonacci数列前20项_面试题精选:神奇的斐波那契数列

    斐波那契数列,其最开始的几项是0.1.1.2.3.5.8.13.21.34-- ,后面的每一项是前两项之和,事实上,斐波那契在数学上有自己的严格递归定义. f0 = 0 f1 = 1 f(n) = f ...

  4. python利用列表计算斐波那契数列前30项_python斐波那契数列的计算方法

    题目: 计算斐波那契数列.具体什么是斐波那契数列,那就是0,1,1,2,3,5,8,13,21,34,55,89,144,233. 要求: 时间复杂度尽可能少 分析: 给出了三种方法: 方法1:递归的 ...

  5. 斐波那契数列大数的压位c语言,HDU 1568 Fibonacci(大数前4位)

    分析:x=1234567.求其前四位数: log10(x)=log10(1.234567)+6. 所以1.234567=10^(log10(x)-6). 1234 =(int) 10^(log10(x ...

  6. 【递归 动态规划 备忘录法】Fibonacci数列(斐波那契数列)(C++)

    一.什么是Fibonacci数列 斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144- 用文字来说,就是从第3项开始,每一项都等于前两项 ...

  7. 斐波拉契数列前n项和 斐波拉契数列第n项

    此篇题解不为别的,纯属纪念,纪念一个已经且也许永远淡出我生活的人... 记不清是大二还是大三了,只记得在教四304实验室,你教我如何用矩阵快速幂来求解斐波拉契数列的第n项,然后考我怎么用类似的方法计算 ...

  8. matlab求斐波那契数列第n项的值,求fibonacci数列第n项的值. 1 1 2 3 5 8....n ?

    [C语言]用递归算法编写一个程序求Fibonacci数列的第n项值 #includeunsignedintFibonacci(intn);intmain(void){inti;for(i=1;i vb ...

  9. python编写递归函数、求斐波那契数列_利用Python实现斐波那契数列的方法实例

    今天我们来使用Python实现递归算法求指定位数的斐波那契数列 首先我们得知道斐波那契数列是什么? 斐波那契数列又叫兔子数列 斐波那契数列就是一个数列从第三项开始第三项的值是第一项和第二项的和依次类推 ...

最新文章

  1. 练习2-14 求奇数分之一序列前N项和 (15 分)
  2. 使用FileZilla Server轻松搭建个人FTP服务器
  3. getcwd和pwd为什么不一样_企业职工,公务员为什么缴纳的养老保险不一样呢?
  4. Vmware虚拟机网络及IP配置
  5. kickstart命令选项
  6. 康宁玻璃ct值计算公式_【钦州】CT室铅板生产厂家
  7. 2021年,朋友圈都在传这8个视频
  8. 分布式代码管理系统Git实践
  9. IPQ4019 QSDK 下添加RM500Q 5G 驱动 qmi拨号链接网络 配置 IPK包方法
  10. JavaScript特效——让文字每秒钟进行变色
  11. Ansys-自适应网格划分-受压薄板学习收获
  12. vot toolkit的超详细使用(多图)
  13. 数学模型学习——图与网络
  14. Executable: C:\PhoneYou\roshan-0.6.6\bin\RoshanQuick.exe
  15. 移植实时操作系统到 risc-v 架构芯片时上下文切换的实现
  16. 相册照片直播小程序开发
  17. 计算机专业用什么轴的键盘,机械键盘什么轴好
  18. wxd719() :大大您的方法有一点小问题:我设成每页35行,在分组区用GROUPNUMBER MOD 1 =0强制分组从新页开始,加上你的recordNumber mod
  19. 计算机保研边缘er如何华丽逆袭?
  20. 推荐必读书籍整理集合

热门文章

  1. win10热点无法开启如何解决
  2. 科研ABC - 工具
  3. DMPR-PS论文详解
  4. 使用python的turtle库函数画圣诞树详细教程
  5. 苹果数据线不能充电_菲耐德 数据线三合一充电线苹果快充线 - 惠券直播 - 一起惠返利网...
  6. Windows 7远程桌面连接Ubuntu 14.04
  7. 2021 CCPC 广州站总结
  8. 1 java基础语法
  9. 几个网赚网站--待验证
  10. YII2自定义错误输出