关于Fibonacci数列的几种求法与POJ 3070

(1) 递推(记忆化搜索)求解:

利用 f i b [ n ] = f i b [ n − 1 ] + f i b [ n − 2 ] fib[n] = fib[n - 1] + fib[n - 2] fib[n]=fib[n1]+fib[n2]( n ≥ 3 n \geq 3 n3)求解,复杂度为O(n)
其中 f i b [ 1 ] fib[1] fib[1] = 1;
f i b [ 2 ] fib[2] fib[2] = 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))
我们设 F [ n ] F[n] F[n] =
[ f i b [ n ] f i b [ n + 1 ] ] \left[ \begin{matrix} fib[n] & fib[n + 1] \end{matrix} \right] [fib[n]fib[n+1]]
构造一个A矩阵
F [ n ] F[n] F[n] = F [ n − 1 ] F[n - 1] F[n1] * A
可得出A =
[ 0 1 1 1 ] \left[ \begin{matrix} 0 & 1 \\ 1 & 1 \end{matrix} \right] [0111]
初始值 F [ 0 ] F[0] F[0] =
[ 0 1 ] \left[ \begin{matrix} 0 & 1 \end{matrix} \right] [01]
这样子 F [ n ] F[n] F[n] = F [ 0 ] F[0] F[0] * A n A^n An
便可以用快速幂求解,复杂度为O( 2 3 2^3 23 log ⁡ n \log n logn)

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) 通项公式:

f i b [ n ] fib[n] fib[n] = 1 5 {1} \over {\sqrt 5} 5 1[( 1 + 5 2 {1 + \sqrt 5} \over {2} 21+5 ) n ^n n - ( 1 − 5 2 {1 - \sqrt 5} \over {2} 215 ) n ^n n]
由于此公式涉及到浮点数,不适合编码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值