码迷,mamicode.com
首页 > 其他好文 > 详细

求Fibonacci数列的第n项

时间:2015-05-11 22:12:24      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:算法   递归   

题目:

      定义Fibonacci数列如下:

技术分享

技术分享方法一:

     递归的方法,代码如下:

#include<iostream>
using namespace std;
int Fibona(int n)
{
int m;
if (n == 0)
return 0;
else if (n == 1 || n == 2)
return 1;
else
{
m = Fibona(n - 1) + Fibona(n - 2);
return m;
}
}
int main()
{
cout << "-------" << endl;
cout << Fibona(17) << endl;
return 0;
}

技术分享方法二:

     从下往上计算,首先根据f(0)和f(1)计算f(2),再根据f(1)和f(2)求出f(3).......

依此类推就可以算出第n项了,时间复杂度为O(n),实际上就是用递推。

long long Fibonacci_Solution2(unsigned n)
{
int result[2] = { 0, 1 };
if (n < 2)
return result[n];
long long fibMinusOne = 1;
long long fibNMinusTwo = 0;
long long fibN = 0;
for (unsigned int i = 2; i <= n; ++i)
{
fibN = fibMinusOne + fibNMinusTwo;
fibNMinusTwo = fibMinusOne;
fibMinusOne = fibN;
}
return fibN;
}

技术分享解法三:

    下面介绍一种时间复杂度是O(logn)的方法。在介绍这种方法之前,先介绍一个数学公式:

{f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1

(注:{f(n+1), f(n), f(n), f(n-1)}表示一个矩阵。在矩阵中第一行第一列是f(n+1),第一行第二列是f(n),第二行第一列是f(n),第二行第二列是f(n-1))

有了这个公式,要求得f(n),我们只需要求得矩阵{1, 1, 1,0}n-1次方,因为矩阵{1, 1, 1,0}n-1次方的结果的第一行第一列就是f(n)。这个数学公式用数学归纳法不难证明。感兴趣的朋友不妨自己证明一下。

现在的问题转换为求矩阵{1, 1, 1, 0}的乘方。如果简单第从0开始循环,n次方将需要n次运算,并不比前面的方法要快。但我们可以考虑乘方的如下性质:

        /  an/2*an/2                      n为偶数时
an=
        \  a(n-1)/2*a(n-1)/2            n为奇数时

要求得n次方,我们先求得n/2次方,再把n/2的结果平方一下。如果把求n次方的问题看成一个大问题,把求n/2看成一个较小的问题。这种把大问题分解成一个或多个小问题的思路我们称之为分治法。这样求n次方就只需要logn次运算了。

实现这种方式时,首先需要定义一个2×2的矩阵,并且定义好矩阵的乘法以及乘方运算。当这些运算定义好了之后,剩下的事情就变得非常简单。完整的实现代码如下所示。

let A={1, 1, 1,0};


int f(int n)
{
int A[4] = { 1, 1, 1, 0 };
int result[4];
power(A, n, result);
return result[0];
}


void multiply(int A[], int B[], int _r[])
{
_r[0] = A[0] * B[0] + A[1] * B[2];
_r[1] = A[0] * B[1] + A[1] * B[3];
_r[2] = A[2] * B[0] + A[3] * B[2];
_r[3] = A[2] * B[1] + A[3] * B[3];
}


void power(int A[], int n, int _r[])
{
if (n == 1){ memcpy(A, _r, 4 * sizeof(int)); return; }
int tmp[4];
power(A, n >> 1, _r);
multiply(_r, _r, tmp);
if (n & 1 == 1)
multiply(tmp, A, _r);
else
memcpy(_r, tmp, 4 * sizeof(int));
}


求Fibonacci数列的第n项

标签:算法   递归   

原文地址:http://blog.csdn.net/wangfengfan1/article/details/45646143

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!