斐波那契数列是这样的一组数列:0,1,1,2,3,5,8,13,21,34,55,89,144,...。通项公式为F(n) = F(n-1) + F(n-2)。原始求法:
int Fibonacci(int N)
{
if (N <= 0)
return 0;
if (N == 1)
return 1;
if (N > 1) return Fibonacci(N-1)+Fibonacci(N-2);
}
利用分治策略:
(F(n),F(n-1)) = (F(n-1),F(n-2))*A
A = {{1,1};{1,0}};
那么
(F(n),F(n-1)) = (F(n-1),F(n-2))*A = (F(n-2),F(n-3))*(A^2) = ... = (F(1),F(0))*(A^(n-1))。
一种实现:
#include <stdio.h>
#include <string.h>
int BASE[2][2] = {{1,1},{1,0}};
int I[2][2] = {{1,0},{0,1}};
void Show(int A[][2],int m,int n)
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
printf("%-3d",A[i][j]);
printf("\n");
}
}
void Multiply(int A[][2],int B[][2],int C[][2])
{
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
C[i][j] = 0;
for(int k=0;k<2;k++)
C[i][j] += A[i][k] * B[k][j];
}
}
void MatrixPow(int A[][2],int B[][2],int n)
{
int C[2][2] = {0};
memcpy(B,I,2*2*sizeof(int));
memcpy(A,BASE,2*2*sizeof(int));
for(;n;n >>= 1)
{
if(n&1)
{
Multiply(A,B,C);
memcpy(B,C,2*2*sizeof(int));
}
Multiply(A,A,C);
memcpy(A,C,2*2*sizeof(int));
}
}
int Fibonacci(int N)
{
if (N <= 0)
return 0;
if (N == 1)
return 1;
if (N > 1) return Fibonacci(N-1)+Fibonacci(N-2);
}
int Fibonacci2(int N)
{
int F1 = 1;
int F0 = 0;
int M1[2][2] = {0};
int M2[2][2] = {0};
MatrixPow(M1,M2,N-1);
Show(M2,2,2);
return F1*M2[0][0] + F0*M2[1][0];
}
int main()
{
Show(BASE,2,2);
Show(I,2,2);
printf("Fib 9 : %d \n",Fibonacci(9));
printf("Fib 8 : %d \n",Fibonacci(8));
printf("Fib 9 : %d \n",Fibonacci2(9));
getchar();
}
输出:
1 1
1 0
1 0
0 1
Fib 9 : 34
Fib 8 : 21
34 21
21 13
Fib 9 : 34
REF:
1,编程之美