编程之美
//递归,时间复杂度O(n),空间复杂度O(n)
int Fibonacci(int n)
{
if(n==0||n==1)return n;
return Fibonacci(n-1)+Fibonacci(n-2);
}
//迭代,时间复杂度O(n),空间复杂度O(1)
int Fibonacci(int n)
{
if(n==0||n==1)return n;
int f1=0,f2=1;
while(n-->=2)
{
f2+=f1;
f1=f2-f1;
}
return f2;
}
//通项公式
int Fibonacci(int n)
{
double tmp=sqrt(double(5));
return int((pow((1+tmp)/2,n)-pow((1-tmp)/2,n))/tmp);
}
//分治,时间复杂度为O(logn)
class Matrix
{
public:
Matrix(int,int,int,int);
Matrix operator*(Matrix);
int m[2][2];
};
Matrix::Matrix(int a,int b,int c,int d)
{
m[0][0]=a;
m[0][1]=b;
m[1][0]=c;
m[1][1]=d;
}
Matrix Matrix::operator*(Matrix rhs)
{
Matrix res(0,0,0,0);
res.m[0][0]=m[0][0]*rhs.m[0][0]+m[0][1]*rhs.m[1][0];
res.m[0][1]=m[0][0]*rhs.m[0][1]+m[0][1]*rhs.m[1][1];
res.m[1][0]=m[1][0]*rhs.m[0][0]+m[1][1]*rhs.m[1][0];
res.m[1][1]=m[1][0]*rhs.m[0][1]+m[1][1]*rhs.m[1][1];
return res;
}
Matrix MatrixPow(Matrix m,int n)
{
Matrix res(1,0,0,1),tmp=m;
for(;n;n>>=1)
{
if(n&1)res=res*tmp;
tmp=tmp*tmp;
}
return res;
}
int Fibonacci(int n)
{
if(n==0||n==1)return n;
return MatrixPow(Matrix(1,1,1,0),n-1).m[0][0];
}
http://www.cnblogs.com/Knuth/archive/2009/09/04/1559951.html
定理1:当n>=2时,f(n)和f(n-1)互素。
证:
gcd(f(n),f(n−1))=gcd(f(n−1),f(n)%f(n−1))=gcd(f(n−1),f(n−2))=...=gcd(f(2),f(1))=1
证毕。
定理2:当n>=1时,若i为奇数, f(i)*f(i)=f(i-1)*f(i+1)+1;若i为偶数,f(i)*f(i)=f(i-1)*f(i+1)-1。
证:数学归纳法
f(1)∗f(1)=f(0)∗f(2)+1f(2)∗f(2)=f(1)∗f(3)+1i:odd,i+1:eveni+2:odd,i+3:evenf(i+2)∗f(i+2)−f(i+1)∗f(i+3)−1=f(i+2)∗f(i+2)−f(i+1)∗f(i+2)−f(i+1)∗f(i+1)−1=f(i)∗f(i+2)−f(i+1)∗f(i+1)−1=0f(i+3)∗f(i+3)−f(i+2)∗f(i+4)+1=f(i+3)∗f(i+3)−f(i+2)∗f(i+3)−f(i+2)∗f(i+2)+1=f(i+1)∗f(i+3)−f(i+2)∗f(i+2)+1=0
证毕。
定理3:f(n)=f(i)*f(n+1-i)+f(i-1)*f(n-i)
证:
f(n)=f(2)∗f(n−1)+f(1)∗f(n−2)=[f(2)+f(1)]∗f(n−2)+f(2)∗f(n−3)=f(3)∗f(n−2)+f(2)∗f(n−3)=...=f(i)∗f(n+1−i)+f(i−1)∗f(n−i)
证毕。
令i=n/2,
f(2i)=f(i)∗f(i+1)+f(i−1)∗f(i)=f(i)∗[2f(i+1)−f(i)]f(2i+1)=f(i)∗f(i+2)+f(i−1)∗f(i+1)=f(i)∗f(i)+f(i+1)∗f(i+1)
int Fibonacci(int n)
{
if(n==0)return 0;
if(n==1||n==2)return 1; //当n>=3时,n>n/2+1
int x=Fibonacci(n/2);
int y=Fibonacci(n/2+1);
if(n&1)return x*x+y*y;
return x*(2*y-x);
}