Fibonacci 数列快速幂

Fibonacci 数列为:1,1,2,3,5,8...这样一个数列,其中F(1)=F(2)=1,F(n)=F(n-1)+F(n-2).

先介绍一下普通的迭代运算,时间复杂度是O(n),这里并没有讨论数目超大的情况,只是用long long来存储数列,没有考虑溢出的情况。

#include "iostream"
using namespace std;

int main()
{
	int n;
	while (cin>>n)
	{
		long long f_0 = 1, f_1 = 1; //定义初值
		long long f_2;              //设一个temp 
		for (int i = 1; i < n; i++)
		{
			f_2 = f_0 + f_1;   //进行赋值迭代
			f_0 = f_1;
			f_1 = f_2;
		}
		cout<<f_0<<endl;
	}

	return 0;
}

接下来介绍一下矩阵的快速幂求法,用数学归纳法可以证明

当n = 2时,成立,

假设当n=k时,成立,

n=k+1时,成立,

所以,因此我们可以根据这个公式来求数列。

利用快速幂求

n为偶数时,

n为奇数时,

这样便可以把时间复杂度降低为O(log(n))。


#include "iostream"
using namespace std;

typedef struct
{
	long long array[4];  //定义一个结构体用来存储一个数组
}Matrix;

Matrix multi(Matrix A, Matrix B) //矩阵乘法
{
	Matrix C;
	C.array[0] = A.array[0]*B.array[0] + A.array[1]*B.array[2];
	C.array[1] = A.array[0]*B.array[1] + A.array[1]*B.array[3];
	C.array[2] = A.array[2]*B.array[0] + A.array[3]*B.array[2];
	C.array[3] = A.array[2]*B.array[1] + A.array[3]*B.array[3];
	
	C.array[0] %= 1000000007;   //对数值取模
	C.array[1] %= 1000000007;
	C.array[2] %= 1000000007;
	C.array[3] %= 1000000007;

	return C;

}

Matrix Mpow(Matrix a, int n)   //做快速幂的乘法
{
	if(n == 1)                 //进行递归调用
		return a; 
	else if( n % 2 == 0)   
	{
		Matrix tempa = Mpow(a, n/2);
		return multi(tempa, tempa);
	}

	else
	{
		Matrix tempb = Mpow(a, (n-1)/2);
		return multi(multi(tempb, tempb), a);
	}
}

int main()
{
	int n;
	Matrix start;
	start.array[0] = 1;   //给矩阵赋初值
	start.array[1] = 1;
	start.array[2] = 1;
	start.array[3] = 0;
	while (cin>>n)
	{
		if(n == 1)
			cout<<1<<endl;
		else
		{
			Matrix finish = Mpow(start, n-1);
			cout<<finish.array[0]<<endl;
		}
	}

	return 0;
}

当时做的时候,还有一个细节是函数返回一个数组的时候该怎么做,后来学习别人的代码,发现可定义一个结构体来存储数组,在函数中直接更改结构体的数组中的数值就好了,之前的想法是直接申请一个数组,用指针来进行值的传递,最后没有成功。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值