此处用了两种方法:
第一种方法是按照模p运算,参考自百度百科
给定一个正整数p,任意一个整数n,一定存在等式
n = kp + r 其中k、r是整数,且 0 ≤ r < p,称呼k为n除以p的商,r为n除以p的
余数。
对于
正整数p和整数a,b,定义如下运算:
取模运算:a mod p 表示a除以p的余数。
模p加法:(a + b) mod p ,其结果是a+b算术和除以p的余数,也就是说,(a+b) = kp +r,则 (a+b) mod p = r。
模p
减法:(a-b) mod p ,其结果是a-b算术差除以p的余数。
模p乘法:(a × b) mod p,其结果是 a × b算术乘法除以p的余数。
可以发现,模p运算和普通的四则运算有很多类似的规律,如:
结合律
|
((a+b) mod p + c)mod p = (a + (b+c) mod p) mod p
((a*b) mod p * c)mod p = (a * (b*c) mod p) mod p
|
交换律
|
(a + b) mod p = (b+a) mod p
(a × b) mod p = (b × a) mod p
|
分配律
|
((a +b)mod p × c) mod p = ((a × c) mod p + (b × c) mod p) mod p
(a×b) mod c=(a mod c * b mod c) mod c
(a+b) mod c=(a mod c+ b mod c) mod c
(a-b) mod c=(a mod c- b mod c) mod c
|
简单的证明其中第一个公式:
((a+b) mod p + c) mod p = (a + (b+c) mod p) mod p
假设
a = k1*p + r1
b = k2*p + r2
c = k3*p + r3
a+b = (k1 + k2) p + (r1 + r2)
如果(r1 + r2) >= p ,则
(a+b) mod p = (r1 + r2) -p
否则
(a+b) mod p = (r1 + r2)
再和c进行模p和运算,得到
结果为 r1 + r2 + r3 的算术和除以p的余数。
对右侧进行计算可以得到同样的结果,得证。
import java.util.Scanner;
public class FibonacciRelative {
public static void main(String[] args) {
/*
Fibonacci数列第n项取余
*/
/*
模p运算
a = k1*p + r1
b = k2*p + r2
c=a+b = (k1 + k2) p + (r1 + r2)
如果(r1 + r2) >= p ,则
(a+b) mod p = (r1 + r2) -p
否则
(a+b) mod p = (r1 + r2)
*/
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] a=new int[n+1];
a[1]=a[2]=1;
for(int i=3;i<a.length;i++){
a[i]=(a[i-1]+a[i-2])%10007;
}
System.out.println(a[n]);
System.out.println("第10项是"+fbc(10));
}
//动态规划线性时间求斐波那契数列第n项
public static long fbc(long n){
if(n<=2) return 1;
long last,nextToLast,answer;
last=nextToLast=answer=1;
for(long i=3;i<=n;i++){
answer=last+nextToLast;
nextToLast=last;
last=answer;
}
return answer;
}
}