分治法求Fibonacci(斐波那契)数列 & 详细代码

分治法求Fibonacci(斐波那契)数列

斐波那契数列

一列有规律的数字 1 1 2 3 5 8 13 21 34 ……

递推公式为Fn = Fn-1 + Fn-2 ,即从第三项开始,每一项等于相邻前两项的和,求Fibonacci数列的方法有很多

现在主要讨论用分治法求Fibonacci数列的第n项

分治法

分治法求Fibonacci数列基于快速幂算法思想
观 察 可 得 [ f ( 2 ) f ( 1 ) f ( 1 ) f ( 0 ) ] = [ 1 1 1 0 ] 观察可得\left[ \begin{matrix} f(2) & f(1) \\ f(1) & f(0) \\ \end{matrix} \right]= \left[ \begin{matrix} 1 & 1 \\ 1 & 0 \\ \end{matrix} \right] [f(2)f(1)f(1)f(0)]=[1110]
用数学归纳法可证明下列公式的正确性(证明略)
[ f ( n + 1 ) f ( n ) f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] n \left[ \begin{matrix} f(n+1) & f(n) \\ f(n) & f(n-1) \\ \end{matrix} \right]= \left[ \begin{matrix} 1 & 1 \\ 1 & 0 \\ \end{matrix} \right]^n [f(n+1)f(n)f(n)f(n1)]=[1110]n
根据此结论结合快速幂算法思想便可求出Fibonacci数列的第n项
快速幂算法参考

代码需要一个求矩阵相乘结果的函数,2*2矩阵result初始为单位矩阵,采用非递归分治法(递归的话需要返回二维数组,造成不必要的麻烦),最后得到result矩阵,根据上述公式可直接找到要求的第n项的结果,时间复杂度为O(logn),代码如下


#include<iostream>
#include<cstdio>
#define long long int
using namespace std;
int Matrix_Mul(int (&m)[2][2],int (&n)[2][2])
{
	int tmp[2][2];
	for(int i=0; i<2;i++)
	{
		for(int j=0; j<2; j++)
		{
			tmp[i][j] = 0;
			for(int k=0; k<2; k++)
				tmp[i][j] += m[i][k] * n[k][j];
		}
	}
	//memcpy(m,tmp,sizeof(tmp));
	for(int i=0;i<2;i++)
		for(int j=0;j<2;j++)
			m[i][j] = tmp[i][j];
}
int Fibonacci(int n)
{
	int result[2][2] = {{1,0},{0,1}};  //单位矩阵 
	int a[2][2] = {{1,1},{1,0}};
	while(n)
	{
		if(n & 1) //相当于n % 2 == 1 
			Matrix_Mul(result,a);
		n = n >> 1;    //相当于n /= 2
		Matrix_Mul(a,a);
	}
	return result[0][1];
} 
int main()
{
	int n;
	cout<<"要查询第几项:";
	cin>>n;
	printf("第%d项为:%d",n,Fibonacci(n));
	return 0 ;
}
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值