<pre name="code" class="cpp">/* 第 19 题: 题目:定义 Fibonacci 数列如下: f(n)=1 n=0 f(n)= 1 n=1 f(n-1)+f(n-2) n=2 输入n,用最快的方法求该数列的第 n 项。 基本的方法有2种 还有个网上方法: 其数学基础: 方阵{ f(n), f(n-1), f(n-1), f(n-2) } = {1, 1, 1,0 }n-1方 即前者表示一个2X2的方阵, 后者表示一个第一行为1,1、第二行为1,0的方阵的n-1次方。 矩阵{1,1,1,0}的n-1次方的结果的第一行第一列就是f(n), 现在的问题转换为求矩阵{1, 1, 1, 0}的乘方。 但我们可以考虑乘方的如下性质: / an/2*an/2 n为偶数时 an= \ a(n-1)/2*a(n-1)/2 n为奇数时 要求得n次方,我们先求得n/2次方,再把n/2的结果平方一下。 分治法。求n变为2个n/2 这样求n次方就只需要logn次运算了。 */ #include <iostream> using namespace std; // 递归方法,时间复杂度O(n) int Fibonacci1(int n) { if (n==0||n==1) return n; else return Fibonacci1(n-1)+Fibonacci1(n-2); } // 额外空间循环方法,时间复杂度O(n) int Fibonacci2(int n) { int result=0; int f1=0,f2=1; if (n==0||n==1) return n; else { for (int i=1;i<n;i++) { result=f1+f2; f1=f2; f2=result; } } return result; } void multiply(int A[], int B[], int result[]) { result[0] = A[0]*B[0] + A[1]*B[2]; result[1] = A[0]*B[1] + A[1]*B[3]; result[2] = A[2]*B[0] + A[3]*B[2]; result[3] = A[2]*B[1] + A[3]*B[3]; } void power(int A[], int n, int result[]) { if (n==1) { memcpy(A,result,4*sizeof(int)); return; } int tmp[4]; power(A, n>>1,result); multiply(result,result,tmp); if (n&1==1) { multiply(tmp, A, result); } else { memcpy(result,tmp,4*sizeof(int)); } } int Fibonacci3(int n) { int A[4] = {1,1,1,0}; int result[4]={1,1,1,0}; power(A, n, result); return result[0]; } int main() { cout<<Fibonacci2(10)<<endl; cout<<Fibonacci1(10)<<endl; cout<<Fibonacci3(10-1)<<endl; return 0; }