斐波那契数列问题的解

解法一:递归

1 int Fib(int n)
2 {
3     if (n <= 0)
4         return 0;
5     else if (n == 1)
6         return 1;
7     else
8         return Fib(n - 1) + Fib(n - 2);
9 }

解法二:递推

 1 int Fib(int n)
 2 {
 3     if (n <= 0)
 4         return 0;
 5     else if (n == 1)
 6         return 1;
 7
 8     int first = 0, second = 1;
 9     int res = 0;
10     for (int i = 1; i < n; ++i) {
11         res = first + second;
12         first = second;
13         second = res;
14     }
15     return res;
16 }

解法三:分治

通项之间有如下关系:

其中矩阵A为:

根据以下公式,可以log(n)次乘法计算出An

 1 class Matrix {
 2 public:
 3     Matrix() : m00(0), m01(0), m10(0), m11(0) {}
 4     Matrix(int m00, int m01, int m10, int m11) :
 5             m00(m00), m01(m01), m10(m10), m11(m11) {}
 6     Matrix& operator=(const Matrix& m) {
 7         this->m00 = m.m00;
 8         this->m01 = m.m01;
 9         this->m10 = m.m10;
10         this->m11 = m.m11;
11         return *this;
12     }
13
14     int m00;
15     int m01;
16     int m10;
17     int m11;
18 };
19 Matrix operator*(const Matrix& lhs, const Matrix& rhs)
20 {
21     Matrix res;
22     res.m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10;
23     res.m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11;
24     res.m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10;
25     res.m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11;
26     return res;
27 }
28
29 Matrix MatrixPow(const Matrix& m, int n)
30 {
31     Matrix res(1, 0, 0, 1);
32     Matrix base = m;
33     for (; n; n >>= 1) {
34         if (n & 1)
35             res = res * base;
36         base = base * base;
37     }
38     return res;
39 }
40
41 int Fib(int n)
42 {
43     if (n <= 0)
44         return 0;
45     else if (n == 1)
46         return 1;
47
48     Matrix A(1, 1, 1, 0);
49     Matrix m = MatrixPow(A, n - 1);
50
51     return m.m00;
52 }

函数MatrixPow的写法似乎不像分治,实际上我们把它写成下面这样就比较明显了,时间复杂度O(logn)。

1 Matrix MatrixPow(const Matrix& m, int n)
2 {
3     if (n == 1)
4         return m;
5     if (n % 2 == 0)
6         return MatrixPow(m * m, n / 2);
7     else
8         return MatrixPow(m * m, n / 2) * m;
9 }
时间: 2024-08-27 21:10:50

斐波那契数列问题的解的相关文章

经典算法详解(1)斐波那契数列的n项

斐波那契数列是一个常识性的知识,它指的是这样的一个数列,它的第一项是1,第二项是1,后面每一项都是它前面两项的和,如:1,1,2,3,5,8,13,21,34,55,89,144,233-- 说明:由于通过递推方式效率低,系统开销大,空间复杂度高,故不考虑. 1 /*斐波那契数列:第一项和第二项为1,后面各项是其前面两项之和*/ 2 /*编写一个函数,输入整数n,求该项的值*/ 3 4 #include<iostream> 5 6 using namespace std; 7 8 int fi

斐波纳契数列

查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ... 样例 给定 1,返回 0 给定 2,返回 1 给定 10,返回 34 虽然这道题是一道入门级的题目,可是在第一遍做的时候并没有多想,直接使用的递归,然后数据通过95%,显示的到47的时候就溢出了.经过学习前辈的经验,该题的收获如下: 方法1:使用递归解,

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波

斐波那契数列和反向计算问题

反向计算:编写一个函数将一个整型转换为二进制形式 反向计算问题,递归比循环更简单 分析:需要理解,奇数的二进制最后一位是1,偶数的二进制最后一位一定是0,联想记忆,这个和整型的奇偶性是一致的,1本身就是奇数,0本身是偶数. 十进制整数转换为二进制整数采用"除2取余,逆序排列"法. 具体做法是:用2整除十进制整数,可以得到一个商和余数,再用2去除商,又会得到一个商和余数,如此进行,直到商为0时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列

斐波那契数列通项公式推导

首先我们要构造一个等比数列,于是设则有. (1)则由已知得 (2) 对照(1)(2)两式得解得 或 .我们取前一解,就会有.设,则有所以数列为等比数列,首项为,公比为所以 .即 (3) 再次构造等比数列,设则有 对照(3)式,可得所以 x=.于是有 设,则有数列为等比数列,首项为,公比为,于是=所以有. 斐波那契数列通项公式推导,布布扣,bubuko.com

算法——动态规划篇——斐波那契数列

斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1960年代起出版了<斐波纳契数列>季刊,专门刊载这方面的研究成果. 以上内容来自百度百科.. 今天主要是想用动态规划的思想求解斐波那契数列,用来观察动态规划带来的优势,空间换时间,不重复求解

51Nod - 1242 斐波那契数列的第N项

斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) = F(n - 1) + F(n - 2) (n >= 2) (1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...) 给出n,求F(n),由于结果很大,输出F(n) % 1000000009的结果即可. Input输入1个数n(1 <= n <= 10^18).Output输出F(n) % 1000000009的结果.Sample Input 11 Sam

斐波那契数列——摘自搜狗百科

1数列公式 递推公式 斐波那契数列:0.1.1.2.3.5.8.13.21.34.55.89.144... 如果设F(n)为该数列的第n项(n∈N*),那么这句话可以写成如下形式: F(0) = 0,F(1)=F(2)=1,F(n)=F(n-1)+F(n-2) (n≥3) 通项公式 通项公式的推导方法一:利用特征方程 线性递推数列的特征方程为: X^2=X+1 解得 X1=(1+√5)/2, X2=(1-√5)/2. 斐波拉契数列则F(n)=C1*X1^n + C2*X2^n ∵F(1)=F(2

c语言:写一个函数,输入n,求斐波拉契数列的第n项(5种方法,层层优化)

写一个函数,输入n,求斐波拉契数列的第n项. 斐波拉契数列:1,1,2,3,5,8...,当n大于等于3时,后一项为前面两项之和. 解:方法1:从斐波拉契数列的函数定义角度编程 #include<stdio.h> int fibonacci(int n) { int num1=1, num2=1, num3=0,i; if (n <= 2) { printf("斐波拉契数列的第%d项为:%d\n",n,num1); } else { for (i = 2; i <