斐波那契数列(Fibonacci)


一、背景介绍

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

【兔子繁殖问题】

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?


二、数学定义

指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……

用数学课表示为:


三、核心代码

方法一:递归

第n个Fibonacci数可递归地计算为:

int fibonacci(int n) {
if (n <= 1)
return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}

方法二:迭代

int fibonacci(int n) {
if (n <= 1)
return 1;
int f = 1, g = 1,ret = 0;
for (int i = 2; i <= n; i++) {
ret = f + g;
f = g;
g = ret;
}
return ret;
}

四、时间复杂度分析

方法一:递归

即可得到O(n^2)。

方法二:迭代

第一种解法比较简单,但是多个元素重复计算,因而时间复杂度较高,为了避免重复计算,可进行循环计算减少时间复杂度,降为O(n)。

五、完整代码

方法一:递归

#include<iostream>
#define scanf scanf_s
using namespace std; int fibonacci(int n) {
if (n <= 1)
return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
} int main() {
printf("请输入下标:");
int n;
scanf_s("%d", &n);
printf("下标为%d的fibonacci数为%d\n",n, fibonacci(n));
return 0;
}

方法二:迭代

#include<iostream>
#define scanf scanf_s
using namespace std; int fibonacci(int n) {
if (n <= 1)
return 1;
int f = 1, g = 1,ret = 0;
for (int i = 2; i <= n; i++) {
ret = f + g;
f = g;
g = ret;
}
return ret;
} int main() {
printf("请输入下标:");
int n;
scanf_s("%d", &n);
printf("下标为%d的fibonacci数为%d\n",n, fibonacci(n));
return 0;
}

六、提升设计

因而计算f(n)就简化为了计算矩阵的(n-2)次方,而计算矩阵的(n-2)次方,我们又可以进行分解,即计算矩阵(n-2)/2次方的平方,逐步分解下去,由于折半计算矩阵次方,因而时间复杂度为O(log n) 。

#include<iostream>
using namespace std; class Matrix {
public:
int n;
int** m;
Matrix(int num) {
m = new int* [num];
for (int i = 0; i < num; i++) {
m[i] = new int[num];
}
n = num;
clear();
}
void clear() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
m[i][j] = 0;
}
}
}
void unit() {
clear();
for (int i = 0; i < n; i++) {
m[i][i] = 1;
}
}
Matrix operator=(const Matrix mtx) {
Matrix(mtx.n);
for (int i = 0; i < mtx.n; ++i) {
for (int j = 0; j < mtx.n; ++j) {
m[i][j] = mtx.m[i][j];
}
}
return *this;
}
Matrix operator*(const Matrix& mtx) {
Matrix result(mtx.n);
result.clear();
for (int i = 0; i < mtx.n; ++i) {
for (int j = 0; j < mtx.n; ++j) {
for (int k = 0; k < mtx.n; ++k) {
result.m[i][j] += m[i][k] * mtx.m[k][j];
}
}
}
return result;
}
}; int main(int argc,const char*argv[]) {
unsigned int num = 2;
Matrix first(num);
first.m[0][0] = 1;
first.m[0][1] = 1;
first.m[1][0] = 1;
first.m[1][1] = 0;
int t;
cout << "请输入下标: ";
cin >> t;
Matrix result(num);
result.unit();
int n = t - 2;
while (n) {
if (n % 2) {
result = result * first;
}
first = first * first;
n = n / 2;
}
cout << (result.m[0][0] + result.m[0][1]) << endl;
return 0;
}

算法1:Fibonacci数列的更多相关文章

  1. c语言经典算法---计算Fibonacci数列

    算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手.下面我就分享一个C语言中比较基础却极为重要的一个算法----计算Fi ...

  2. java算法 蓝桥杯算法训练 Fibonacci数列

    问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. 输入格式 输入包含一个整数n ...

  3. 算法——js(Fibonacci数列)

    斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家列昂纳多·斐波那契(Leonardoda Fibonacci[1]  )以兔子繁殖为例子而引入,故又称为“兔子数列”,指 ...

  4. 算法设计与分析 1.2 不一样的fibonacci数列 (矩阵快速幂思想)

    题目描述 Winder 最近在学习 fibonacci 数列的相关知识.我们都知道 fibonacci 数列的递推公式是F(n) = F(n - 1) + F(n - 2)(n >= 2 且 n ...

  5. 程序员面试题精选100题(16)-O(logn)求Fibonacci数列[算法]

    作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:定义Fibonacci数列如下: /  0                      n=0 f(n)=      ...

  6. 【算法】Fibonacci(斐波那契数列)相关问题

    一.列出Fibonacci数列的前N个数 using System; using System.Collections.Generic; using System.Linq; using System ...

  7. 算法设计与分析 1.2 不一样的fibonacci数列

    ★题目描述 fibonacci 数列的递推公式是F(n) = F(n-1) + F(n-2)(n >= 2 且 n 为整数). 将这个递推式改为F(n) = aF(n-1) + bF(n-2)( ...

  8. fibonacci 数列及其应用

    fibonacci 数列及其延展 fibonacci计算 fibonacci数列是指 0,1,1,2,3,5,8,13,21……这样自然数序列,即从第3项开始满足f(n)=f(n-1)+f(n-2): ...

  9. 蓝桥网试题 java 入门训练 Fibonacci数列

    ---------------------------------------------------------------------------------------------------- ...

  10. Fibonacci数列的解法

    Fibonacci数列的解法: 1.递归算法 递归的概念,我说不清楚,语文不好.但是核心思想,我认为就是入栈出栈.比方说,你想要求得某个结果,如果一步求解不出来,那么先把最后一步的计算步骤进栈,先不考 ...

随机推荐

  1. 使用极速全景图下载大师下载720yun全景图片(一键下载建E、720云全景原图)

    VR全景图片下载 软件简介 极速全景图下载大师下载地址: 点击进入下载页面 极速全景图下载大师(VR全景图下载器)软件官网: 点击进入官网 极速全景图下载大师如何下载720yun全景图片 1.首先,在 ...

  2. 【.NET8】访问私有成员新姿势UnsafeAccessor(下)

    前言 书接上回,我们讨论了在.NET8中新增的UnsafeAccessor,并且通过UnsafeAccessor访问了私有成员,这极大的方便了我们代码的编写,当然也聊到了它当前存在的一些局限性,那么它 ...

  3. 使用shuffle sharding增加容错性

    使用shuffle sharding增加容错性 最近在看kubernetes的API Priority and Fairness,它使用shuffle sharding来为请求选择处理队列,以此防止高 ...

  4. Redis 命令工具

    --- Redis 命令工具 --- redis-server Redis 服务器启动命令 redis-cli shutdown 停止服务 redis-benchmark:性能测试工具,用于检测 Re ...

  5. c语言代码练习3

    //查看数字是否存在于数组中#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { int i = 0; int ...

  6. DevOps|研发效能解决的是企业效率问题

    研发效能并不能解决企业效益问题 它不是利润中心,不能给你带来直接收入(研发效能相关工具厂商做咨询.出方案.卖工具除外).想要解决企业效益问题,依赖于企业战略.业务/产品.组织.运营.创新等其他方面. ...

  7. jmeter生成HTML性能测试报告(非GUI的命令)

    非GUI的命令(在cmd执行即可 不需要打开jmeter) 使用命令:jmeter  -n  -t  [jmx file]  -l  [jtl file]  -e  -o   [report path ...

  8. [GXYCTF 2019]Ping Ping Ping

    题目就是ping,而且这还有一个查询窗口,就随便查询试试 ping了一下本地,发现没有什么很大的作用,给出了提示是php可以执行系统函数这就感到神奇了,就还是上网搜了搜 发现可以在查询IP后面进行拼接 ...

  9. 创建一个自己的 Linux系统

    简单来说就是一个文件传递的机制,首先创建/安装一个硬盘,然后把前硬盘中的一部分文件先转移到Linux系统上,再通过Linux系统转移到创建的新硬盘,之后用虚拟机,把新硬盘装在其中,就可以在新硬盘上做到 ...

  10. NewStarCTF 2023 公开赛道 WEEK4|MISC 部分WP

    R通大残 1.题目信息 R通大残,打了99,补! 2.解题方法 仔细分析题目,联想到隐写的R通道. 首先解释一下:R是储存红色的通道,通道里常见有R(红).G(绿).B(蓝)三个通道,如果关闭了R通道 ...