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