此题对数学知识的要求比较高,9楼版主所说的循环,程序上的验证是正确的,从数学原理上的解释,我还没有弄明白,望能解惑。
下面是我从另一个角度的探索,从斐波那契的递推公式Fn=Fn-1+Fn-2,其中F1=F2=1可以得出以下两个关系,
F(n+m-1)=F(n-1)*F(m-1)+F(n)*F(m)
F(n+m)=F(n-1)*F(m)+F(n)*(F(m-1)+F(m))
这两个公式可以做到,从n-1项,n项,m-1项,m项这4项的值得到m+n-1项,m+n项的值,大概就是可以做到两项之和,这样在计算某一项时,就可以不用一项一项的去求,从某一项开始,直接加上一个合适的项就可以了。以下是代码实现:
程序代码:
下面是我从另一个角度的探索,从斐波那契的递推公式Fn=Fn-1+Fn-2,其中F1=F2=1可以得出以下两个关系,
F(n+m-1)=F(n-1)*F(m-1)+F(n)*F(m)
F(n+m)=F(n-1)*F(m)+F(n)*(F(m-1)+F(m))
这两个公式可以做到,从n-1项,n项,m-1项,m项这4项的值得到m+n-1项,m+n项的值,大概就是可以做到两项之和,这样在计算某一项时,就可以不用一项一项的去求,从某一项开始,直接加上一个合适的项就可以了。以下是代码实现:
程序代码:
#include<stdio.h>
#include<stdlib.h>
#define modN 10007
int main()
{
unsigned int f0,f1 ,rs0,rs1;
unsigned int i,n,m,end,temp0,temp1;
while(1)
{
if(scanf("%d",&n)==EOF )break;
m=n;
f0=0;
f1=1;
rs0=1;
rs1=0;
i=1;
end=(m&0xffff0000)==0?16:32;//m<=0xffff0000时只计算至二进制数低16位
while(i<=end)
{
if (m&1)
{
// F(n+m-1)=F(n-1)*F(m-1)+F(n)*F(m)
// F(n+m)=F(n-1)*F(m)+F(n)*(F(m-1)+F(m))
// 从rs0,rs1,f0,f1得到rs1+f1-1,rs1+f1 各项值的累加
temp0=(rs0*f0+rs1*f1)%modN;
temp1=(rs0*f1+rs1*(f0+f1))%modN;
rs0=temp0;
rs1=temp1;
}
// F(n+m-1)=F(n-1)*F(m-1)+F(n)*F(m)
// F(n+m)=F(n-1)*F(m)+F(n)*(F(m-1)+F(m))
// 从f0,f1,f0,f1得到f0+f1-1,f0+f1 项数增加一倍,也就是二进制位向上一位 f1 始终记录2^i项的值
temp0=(f0*f0+f1*f1)%modN;
temp1=(f0*f1+f1*(f0+f1))%modN;
f0=temp0;
f1=temp1;
m/=2;
i++;
}
printf("%u\n",rs1);
}
return 1;
}









以前看到的算法