14天阅读挑战赛
努力是为了不平庸~

目录

1.神奇的兔子数列

1.1问题分析

1.2斐波那契数列

1.3算法设计

1.3.1递归代码

1.3.2递归的改进,O(n)的代码

1.3.3时间复杂度为O(logN)的代码

1.3.4 O(logN)算法的思路

1.3.5 main函数及测试结果

2.生活中的斐波那契数列

3.黄金比例

4.斐波那契数列的一些应用

4.1矩形面积

4.2杨辉三角

4.3跳台阶问题


1.神奇的兔子数列

假设第1个月有1对初生的兔子,第2个月进入成熟期,第3个月开始生育兔子,而1对成熟的兔子每月会生1对兔子,兔子永不死去......那么,由1对初生的兔子开始,12个月后会有多少对兔子呢?

1.1问题分析

不妨拿新出生的1对小兔子分析。

第1个月,小兔子1没有繁殖能力,所以还是1对。

第2个月,小兔子1进入成熟期,仍然是1对。

第3个月,小兔子1生了一对小兔子2,于是这个月共有2对兔子。

第4个月,小兔子1又生了小兔子3,因此共有3対兔子。

第5个月,小兔子1生了一对小兔子4,而在第3个月出生的小兔子2也生下一对小兔子5,因此共有5(2+3=5)对兔子。

第6个月,兔子123各生下1对小兔子,新生的3对兔子加上原有的5对兔子,这个月共有8(3+5=8)对兔子。

......

下图分别表示新生兔子、成熟期兔子和生育期兔子的繁殖过程:

这个数列有如下十分明显的特点:从第3个月开始,当月的兔子数=上月兔子数+当月新生兔子数,而当月新生兔子数正好等于上上月的兔子数。因此,前面相邻两项之和便构成一项,换言之:

当月兔子数 = 上月兔子数 + 上上月的兔子数

1.2斐波那契数列

斐波那契数列如下:

1,1,2,3,5,8,13,21,34,55,......

递归表达式如下:

1.3算法设计

1.3.1递归代码

//算法1:递归 O(n²)
unsigned long Func1(int n)
{if (n == 1 || n == 2){return 1;}return Func1(n - 1) + Func1(n - 2);
}

1.3.2递归的改进,O(n)的代码

//算法2:用中间值保存变量O(n)
double Func2(int n)
{double fir = 1;double sec = 1;if (n == 1 || n == 2){return 1;}cout << "数列:1 1";double result = 0;for (int  i = 3; i <=n; i++){result = fir + sec;fir = sec;sec = result;printf(" %.0f", result);}cout << endl << endl;return result;
}

1.3.3时间复杂度为O(logN)的代码

//算法3:O(logn)
struct Matrix
{double m11;double m12;double m21;double m22;
};//矩阵相乘
Matrix MatrixMul(const Matrix& lhs, const Matrix& rhs)
{Matrix result;result.m11 = lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21;result.m12 = lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22;result.m21 = lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21;result.m22 = lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22;return result;
}Matrix Fib(Matrix base, int num)
{if (num == 1){return base;}Matrix orgMatrix = Fib(base, num / 2);Matrix result = MatrixMul(orgMatrix, orgMatrix);//如果num是奇数,需要再做一次与初矩阵的相乘if (num % 2){result = MatrixMul(result, base);}return result;
}double Func3(int n)
{Matrix base = { 1,1,1,0 };if (n == 1 || n == 2){return 1;}Matrix result = Fib(base, n);printf("\n算法3运行结果:%.0f\n", result.m11 + result.m21);return result.m11 + result.m21;
}

1.3.4 O(logN)算法的思路

1.3.5 main函数及测试结果

//Fibonaqi
#include <windows.h>
#include <time.h>
namespace Fibonaqi
{//算法1:递归 O(n²)unsigned long Func1(int n){if (n == 1 || n == 2){return 1;}return Func1(n - 1) + Func1(n - 2);}//算法2:用中间值保存变量O(n)double Func2(int n){double fir = 1;double sec = 1;if (n == 1 || n == 2){return 1;}cout << "数列:1 1";double result = 0;for (int  i = 3; i <=n; i++){result = fir + sec;fir = sec;sec = result;printf(" %.0f", result);}cout << endl << endl;return result;}//算法3:O(logn)struct Matrix{double m11;double m12;double m21;double m22;};//矩阵相乘Matrix MatrixMul(const Matrix& lhs, const Matrix& rhs){Matrix result;result.m11 = lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21;result.m12 = lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22;result.m21 = lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21;result.m22 = lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22;return result;}Matrix Fib(Matrix base, int num){if (num == 1){return base;}Matrix orgMatrix = Fib(base, num / 2); //通过二分法的方式,实现时间复杂度为O(logn)的效果Matrix result = MatrixMul(orgMatrix, orgMatrix);if (num % 2){result = MatrixMul(result, base);}return result;}double Func3(int n){Matrix base = { 1,1,1,0 };if (n == 1 || n == 2){return 1;}Matrix result = Fib(base, n);printf("\n算法3运行结果:%.0f\n", result.m11 + result.m21);return result.m11 + result.m21;}void Run(){cout << "输入第n个数:";int num = 0;cin >> num;cout << endl;//开始运行时间 -- 算法1long startTime = clock();int fib_result = Fibonaqi::Func1(num);//结束运行时间long endTime = clock();cout << "算法1运行时间:" << endTime - startTime << endl;cout << "结果:" << fib_result << endl << endl;//开始运行时间 -- 算法2startTime = clock();double result = Fibonaqi::Func2(num);//结束运行时间endTime = clock();cout << "算法2运行时间:" << endTime - startTime << endl;printf("算法2运行结果:%.0f\n", result);//开始运行时间 -- 算法3startTime = clock();result = Fibonaqi::Func3(num - 2);//注意这里输入的数减了2//结束运行时间endTime = clock();cout << "算法3运行时间:" << endTime - startTime << endl;}
}
int main()
{Fibonaqi::Run();system("pause");return 0;
}

2.生活中的斐波那契数列

科学家经研究,在植物的叶、枝、茎等排列中发现了斐波那契数!例如,在树木的枝干上选一片叶子,记数为1,然后依序点数叶子(假定没有折损),直至数到与那片叶子正对的位置,则期间的叶子数多半是斐波那契数列。叶子从一个位置到达下一个正对的位置称为一个循回。叶子在一个循回中旋转的圈数也是斐波那契数。在一个循回中,叶子数与叶子旋转圈数的比称为叶序(源自希腊词,意为叶子的排列)比。多数植物的叶序比呈现为斐波那契数的比。例如,蓟的头部具有34条顺时针旋转和21条逆时针的斐波那契螺旋,向日葵的种子的圈数与种子数、菠萝的外部排列等同样具有这样的特性,如下图:

观察延龄草、野玫瑰、南美血根草、大波斯菊、金凤花、耧斗菜、百合花、蝴蝶花的花瓣,可以发现它们的花瓣为斐波那契数:3,5,8,13,21,......,如下图:

3.黄金比例

有趣的是,这样一个完全由自然数组成的数列,通项公式却是用无理数来表达的,而且当n趋向于无穷大时,斐波那契数列中的前一项与后一项的比值越来越逼近黄金分割数0.618:  1/1=1,        1/2=0.5,        2/3=0.666,......,3/5=0.6,        5/8=0.625,......,55/89=0.617977,        144/233=0.618025,......,46368/75025=0.6180339886......

越到后面,这些比值越接近黄金分割数:

4.斐波那契数列的一些应用

4.1矩形面积

斐波那契数列与矩形面积的生成相关,由此可以导出一个斐波那契数列的一个性质。斐波那契数列前几项的平方和可以看做不同大小的正方形,由于斐波那契的递推公式,它们可以拼成一个大的矩形。这样所有小正方形的面积之和等于大矩形的面积。则可以得到如下的恒等式:

4.2杨辉三角

将杨辉三角左对齐,成如图所示排列,将同一斜行的数加起来,即得一数列1、1、2、3、5、8、……

4.3跳台阶问题

有个n阶台阶,一次可以走一个台阶,也可以走两个台阶,走到n阶台阶有多少种走法?

趣学算法--斐波那契数列相关推荐

  1. Java数据结构与算法---斐波那契数列Fibonacci

    Java数据结构与算法-斐波那契数列Fibonacci 原理都很简单,直接上代码: package cn.m_fibonacci;public class Fibonacci {public stat ...

  2. 最优化算法-斐波那契数列搜索

    斐波那契数列搜索,参考Edwin<最优化导论>第四版7.3章节,算法采用go语言实现. /****************************************** FileNa ...

  3. 427-动态规划算法-斐波那契数列

    动态规划算法求解斐波那契数列 状态:dp数组,存储已经求解的子问题的最优解 递归版本的动态规划算法 //参数n表示斐波那契数列中数字的个数. //返回相应个数的斐波那契数列数字的值. int fabn ...

  4. 经典算法——斐波那契数列

    斐波那契数列的经典解法是采用递归的方式: f(n)=f(n-1)+f(n-2)   n>2 f(1)=1      n=1 f(2)=1      n=2 按照这个思路可以写出递归算法: #in ...

  5. 算法-斐波那契数列:兔子序列

    利用递归函数求斐波那契数列(兔子序列) 1.1.2.3.5.8.13.21-求第n个数是几,n任意一个数大家可以自定义,比如10,20等 分析: 从给出的数列中,可知, n=1时→1 n=2时→1 n ...

  6. C语言中经典算法——斐波那契数列的几种算法

    斐波那契数列的递推公式: 我们尝试计算斐波那契数列的第n项并输出. 1.递归法 #include<stdio.h> int fib(int m) {if(m>=3){return f ...

  7. 算法—斐波拉契数列(跳楼梯问题)

    问题描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 这道题一看,就会轻易的知道用递归,f(1)=1;f(2)=1;f(n)=f(n-1)+f(n-2 ...

  8. 算法-斐波那契数列(黄金分割数列|兔子数列)

    前言 斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数列 ...

  9. 算法 - 斐波那契数列问题(转自微信公众号码农翻身)

    注:转自微信公众号漫画:什么是动态规划? 问题描述: 算法:有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶.要求用程序来求出一共有多少种走法. 解析:如果只差最后一步就能走 ...

最新文章

  1. opencv中ArUco模块实践(1)
  2. 5.JasperReports学习笔记5-其它数据生成动态的报表(WEB)
  3. MYSQL 集群的数据节点错误信息归档
  4. webstorm打开网页_网页前端之HTML+CSS+JS
  5. linux 套接字 文件 路径,linux – 识别unix域套接字连接的另一端
  6. 面试官:说说Java中java.lang.Void和void有什么作用和区别?
  7. 关于xinetd报错
  8. LSTM公式详解推导
  9. Zetcode GUI 教程
  10. 骚年快醒醒,你适合转行做前端吗?
  11. 进程虚拟地址空间之数据分区存放【转】
  12. 2018.08.17 洛谷P3135 [USACO16JAN]堡哞(前缀和处理)
  13. python做词典_字典实现
  14. topsis法_论文荐读|基于风险响应概念模型和改进TOPSIS模型的半干旱流域生态风险综合评价——以渭河流域为例...
  15. 由于没有远程桌面授权服务器可以提供许可证,远程会话被中断。
  16. mockito验证参数_Mockito验证
  17. 书籍_《未来世界的幸存者》阮一峰--5/5
  18. JAVA计算机毕业设计小型超市管理系统(附源码、数据库)
  19. 君正T30移植ntp
  20. 李元翼 梧里 徒死無益

热门文章

  1. 广东政务微信的服务器设置,广东又一省级政务微信号上线!
  2. easyexcel 设置超链接或附件地址
  3. Hash表(哈希表、散列表)
  4. 关于垃圾回收CollectGarbage()的使用
  5. SyntaxError: Non-UTF-8 code starting with '\xb6' in file XX.py
  6. 1086 就不告诉你(C语言)
  7. clone.weekday is not a function
  8. vscode标签插件bookmarks
  9. 公文、附件和版式正文的设置
  10. 星闪:咫尺之间,联接智能世界