Fibonacci数列第n项对10007取余

此处用了两种方法:


第一种方法是按照模p运算,参考自百度百科

模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的余数。
对右侧进行计算可以得到同样的结果,得证。

第二种方法是先通过动态规划求得Fibonacci数列的第n项,再除以10007


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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值