(1) 递推(记忆化搜索)求解:
利用
(
)求解,复杂度为O(n)
其中
= 1;
= 1;
参考代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
long long fib[100000];
const int mod = 1e9 + 7;
int main(){
int n, i;
scanf("%d", &n);
fib[1] = 1;
fib[2] = 1;
for(i = 3; i <= n; i++)
fib[i] = (fib[i - 1] + fib[i - 2]) % mod;
printf("%lld\n", fib[n]);
return 0;
}
(2) 利用矩阵乘法:
(这就是poj3070的解法,它的题意为:求Fibonacci第n项的后4位(%10000))
我们设
=
构造一个A矩阵
=
* A
可得出A =
初始值
=
这样子
=
*
便可以用快速幂求解,复杂度为O(
)
POJ3070代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod = 10000;
void mul(int f[2], int a[2][2]){
int c[2], j, k;
memset(c, 0, sizeof(c));
for(j = 0; j < 2; j++)
for(k = 0; k < 2; k++){
c[j] = (c[j] + (long long)f[k] * a[k][j]) % mod;
}
memcpy(f, c, sizeof(c));
}
void mulmyself(int a[2][2]){
int c[2][2];
int i, j, k;
memset(c, 0, sizeof(c));
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
for(k = 0; k < 2; k++)
c[i][j] = (c[i][j] + (long long)a[i][k] * a[k][j]) % mod;
memcpy(a, c, sizeof(c));
}
int main(){
int n,i;
while(1){
scanf("%d", &n);
if(n == -1) break;
int f[2] = {0, 1};
int a[2][2] = {{0, 1}, {1, 1}};
while(n > 0){//快速幂
if(n & 1) mul(f, a);
mulmyself(a);
n >>= 1;
}
printf("%d\n", f[0]);
}
return 0;
}
(3) 通项公式:
=
[(
)
- (
)
]
由于此公式涉及到浮点数,不适合编码。