问题概述:求出第n个斐波那契数列的前4位,其中a[0]=0、a[1]=1,n可高达100000000
输入样例: 对应输出:
35 9227
参考资料:http://blog.csdn.net/u013486414/article/details/46834111
此题难点:将递推公式化为通项公式(特征根法),并化简通项公式
入门特征根法:
一阶线性递推式a[n+1] = c*a[n]+d(c、d为任意常数)求法:
①设方程 x = c*x+d 解出 x = x0
②则a[n]的通项公式就为 a[n] = b[n]+x0(其中b[n]为等比数列)
③通过已知的a[1]和a[2]即可求出b[1]和b[2],从而求出a[n]的通项公式
二阶线性递推式a[n+2] = c*a[n+1]+d*a[n]+e(c、d、e为任意常数)求法:
①设方程 x² = c*x+d 解出相应的x1, x2;
②则a[n]的通项公式就为a[n] = A*x1^(n-1)+B*x2^(n-1)
③通过已知的a[1]和a[2]求出A和B
附录:floor()函数:
功能:向下取整
例如: floor(3.14) = 3.0
floor(9.999999) = 9.0
floor(-3.14) = -4.0
floor(-9.999999) = -10
除此之外还有ceil()为向上取整
附录2:高阶线性特征多项式(基础:母函数)
无重根:
有重根:
有共轭复根:
来源:学堂在线(组合数学)
#include<stdio.h>
#include<math.h>
int main(void)
{
int n, i;
int a[24] = {0,1};
double b, ans;
for(i=2;i<=20;i++)
a[i] = a[i-1]+a[i-2];
while(scanf("%d", &n)!=EOF)
{
if(n<=20)
{
printf("%d\n", a[n]); /*当a[n]不足4位时,直接输出*/
continue;
}
/*用特征根法求出斐波那契数列的通项公式为a[n] = 1/sqrt(5.0)*((1.0+sqrt(5.0))/2.0)^n - 1/sqrt(5.0)*((1.0-sqrt(5.0))/2.0)^n*/
b = (1.0+sqrt(5.0))/2.0; /*↑↑这一部分太小啦可以忽略不计↑↑*/
ans = n*log10(b)-0.5*log10(5.0); /* ans = log10(a[n]) */
ans -= floor(ans); /* ans = log10(b[n]) (其中bn中的个位为an中的最高位,b[n]小数点后1位为a[n]中的次高位……)*/
ans = pow(10, ans); /* ans = b[n] */ /*↑↑例如a[n] = 182852345456, 则b[n] = 1.82852345456↑↑*/
ans *= 1000; /*因为题目要求a[n]的前a4位,则将ans=b[n]*1000 */
printf("%d\n", (int)ans);
}
return 0;
}