Tribonacci(泰波那契)数列前n项和的求解问题

 
Tribonacci数列是斐波那挈数列的扩展

 
很有趣的,我们可以发现 

这是Tribonacci数列的一些深入研究 
下面是贴代码的时间了: 
解法一(半产品) 
这种方法就不解释了,不懂就去看看最笨的方法递归求解,而这是对递归求解的优化

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNext()) {

            long l = scanner.nextLong();
            long r = scanner.nextLong();
            long sum = 0;
             sum = sum_tribonacci(l, r);
             System.out.println(sum % 1000000007);
//          for (long i = 0; i <= 100l; i++) {
//              sum = sum_tribonacci(0, i);
//              System.out.println(i + "---------------------------" + sum
//                      % 1000000007l);
//          }

        }
    }

    public static long sum_tribonacci(long l, long r) {
        long n1 = 0, n2 = 0, n3 = 0;
        long u1, u2;
        long sum = 0;
        if (r < 3) {
            return (r - l + 1);
        }

        n1 = 0;
        n2 = 1;
        n3 = 2;
        // n1 = 1;
        // n2 = 1;
        // n3 = 1;
        long n4 = 0;
        if (l < 3) {
            // for (long i = 3; i <= r; i++) {
            for (long i = 3; i <= r + 1; i++) {
                n4 = n3 + n2 + n1;
                n1 = n2;
                n2 = n3;
                n3 = n4;
            }
            sum = n3 - l;
            return sum;

        } else {
            // for (long i = 3; i <= l; i++) {
            for (long i = 3; i <= l; i++) {
                n4 = n3 + n2 + n1;
                n1 = n2;
                n2 = n3;
                n3 = n4;
            }
            long sum1 = n3;
            // sum+=n4;
            for (long i = l + 1; i <= r + 1; i++) {
                n4 = n3 + n2 + n1;
                n1 = n2;
                n2 = n3;
                n3 = n4;
            }
            long sum2 = n3;
            return sum2 - sum1;
        }
    }

}

解法二 
 
所以这里关键是要求出矩阵A 
可以用前5项求出矩阵(数列{1、2、3、6、11…}依题意这是数列{1、1、1、3、5…}前n-1项的和,依然满足Tribonacci规则) 
这里矩阵的n次幂,我采用的是二分法。

  1 import java.math.BigDecimal;
  2 import java.util.Scanner;
  3
  4 public class CopyOfMain2 {
  5     public static BigDecimal i1000000007 = new BigDecimal(
  6             String.valueOf(1000000007));
  7     //这里定义了四个数,其实是为了下面BigDecimal数组的初始化做准备
  8     public static BigDecimal i3 = new BigDecimal(String.valueOf(3));
  9     public static BigDecimal i2 = new BigDecimal(String.valueOf(2));
 10     public static BigDecimal i1 = new BigDecimal(String.valueOf(1));
 11     public static BigDecimal i0 = new BigDecimal(String.valueOf(0));
 12
 13     public static void main(String[] args) {
 14         Scanner scanner = new Scanner(System.in);
 15
 16         while (scanner.hasNext()) {
 17
 18             long l = scanner.nextLong();
 19             long r = scanner.nextLong();
 20             BigDecimal[] sum = {i0,i0};
 21
 22
 23             sum = Tribonacci(l, r).divideAndRemainder(i1000000007);
 24             if(sum[1].longValue()<0)System.out.println(sum[1].add(i1000000007));
 25             else System.out.println(sum[1]);
 26             //这是比较笨的方法,用这种遍历的求和方式当然会超时
 27             // for (long i = l; i <= r; i++) {
 28             //    sum += Tribonacci(i);
 29             // }
 30             // for(long i =0; i <= 100l; i++){
 31             //    sum=Tribonacci(0,i);
 32             //    System.out.println(i+"---------------------------"+sum %
 33             //    1000000007l);
 34             // }
 35         }
 36     }
 37
 38     public static BigDecimal Tribonacci(long l, long r) {
 39         BigDecimal sum = i0;
 40         if (r < 3) {
 41             for (long i = l; i <= r; i++) {
 42                 sum = new BigDecimal(String.valueOf(r - l + 1));
 43             }
 44             return sum;
 45         }
 46         BigDecimal[][] base = { { i1, i1, i0 }, { i1, i0, i1 }, { i1, i0, i0 } };
 47         if (l >= 3l) {
 48             BigDecimal[][] res1 = matrixPower(base, l - 3);
 49
 50             BigDecimal[][] res = matrixPower(base, r - 2);
 51             // long[][] res = muliMatrix(res1,matrixPower(base, r- l+1));
 52             return (res[0][0].subtract(res1[0][0])).multiply(i3)
 53                     .add((res[1][0].subtract(res1[1][0])).multiply(i2))
 54                     .add((res[2][0].subtract(res1[2][0])));
 55         } else {
 56             BigDecimal[][] res = matrixPower(base, r - 2);
 57             return (res[0][0].multiply(i3).add(res[1][0].multiply(i2))
 58                     .add(res[2][0]).subtract(new BigDecimal(String.valueOf(l))));
 59         }
 60
 61     }
 62     //求Tribonacci数列每一项的方法
 63     // public static long Tribonacci(long n) {
 64     // if (n == 0l || n == 1l || n == 2l) {
 65     // return 1;
 66     // } else if (n == 3l)
 67     // return 3;
 68     // long[][] base = { { 1l, 1l, 0l}, { 1l, 0l, 1l }, { 1l, 0l, 0l } };
 69     // long sum = 0l;
 70     //
 71     // long[][] res = matrixPower(base, n - 3l);
 72     //
 73     // return 3l * res[0][0] + res[1][0] + res[2][0];
 74     // }
 75
 76     public static BigDecimal[][] matrixPower(BigDecimal[][] base, long p) {
 77         BigDecimal[][] res = new BigDecimal[base.length][base[0].length];
 78         for (int i = 0; i < res.length; i++) {
 79             for (int j = 0; j< res[0].length; j++) {
 80                 if (i == j) {
 81                     res[i][j] = i1;
 82                 } else
 83                     res[i][j] = i0;
 84             }
 85
 86         }
 87         BigDecimal tmp[][] = base;
 88         for (; p != 0; p >>= 1) {
 89             if ((p & 1) != 0) {
 90                 res = muliMatrix(res, tmp);
 91             }
 92             tmp = muliMatrix(tmp, tmp);
 93         }
 94         return res;
 95     }
 96
 97     private static BigDecimal[][] muliMatrix(BigDecimal[][] m1,
 98             BigDecimal[][] m2) {
 99         BigDecimal[][] res = new BigDecimal[m1.length][m2[0].length];
100         for (int i = 0; i < res.length; i++) {
101             for (int j = 0; j< res[0].length; j++) {
102                 res[i][j] = i0;
103             }
104         }
105         for (int i = 0; i < m1.length; i++) {
106             for (int j = 0; j < m2[0].length; j++) {
107                 for (int k = 0; k < m2.length; k++) {
108
109                         res[i][j] = res[i][j].add(m1[i][k].multiply(m2[k][j])).divideAndRemainder(i1000000007)[1];
110
111                 }
112             }
113         }
114         return res;
115
116     }
117
118 }
时间: 2024-10-12 20:45:18

Tribonacci(泰波那契)数列前n项和的求解问题的相关文章

黑马入学基础测试(三)求斐波那契数列第n项,n&lt;30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

.获得用户的输入 计算      3打印就行了.   这里用到了java.util.Scanner   具体API  我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复读取 自己写的代码: package com.itheima; import java.util.Scanner; public class Test3 { /** * 3.求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55 * * @author

求斐波那契数列第n项,n&lt;30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

public class Test4 { public static void main(String[] args) { int n; int fn; Scanner scanner=new Scanner(System.in); System.err.println("请输入30以内的整数:"); n=scanner.nextInt(); fn=peibo(n); System.out.println("斐波那契数列第"+n+"项为:"+fn

经典算法详解(1)斐波那契数列的n项

斐波那契数列是一个常识性的知识,它指的是这样的一个数列,它的第一项是1,第二项是1,后面每一项都是它前面两项的和,如:1,1,2,3,5,8,13,21,34,55,89,144,233-- 说明:由于通过递推方式效率低,系统开销大,空间复杂度高,故不考虑. 1 /*斐波那契数列:第一项和第二项为1,后面各项是其前面两项之和*/ 2 /*编写一个函数,输入整数n,求该项的值*/ 3 4 #include<iostream> 5 6 using namespace std; 7 8 int fi

NYOJ 461-Fibonacci数列(四)(求斐波那契数列前4位)

题目地址:NYOJ 461 思路:斐波那契数列的通项公式为 然后下一步考虑如何产生前4位: 先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);假设给出一个数10234432, 那么log10(10234432)=log10(1.0234432*10^7)[用科学记数法表示这个数]=log10(1.0234432)+7; log10(1.0234432)就是log10(10234432)的小数部分. log10(1.0234432)=0.0

用递归和迭代写斐波那契数列,前n列的和

首先注意: 方法不调用不执行,调用才执行,并且把值返回到方法的调用处!! public class Fei_Bo_Na_Qi{    public static void main(String[] args){        int m = 100;        System.out.println( "斐波那契数列的第 "+m+" 位数为: "+m1(m) );//  在输出的时候调用函数    }    public static int  m1(int i

JS写斐波那契数列第n项

斐波那契数列:1 1 2 3 5 8 13 21 34 ... 数列特点:f(n)=f(n–1)+f(n–2)  后一项等于前两项之和 var a=0: var b=1: var c: var n=2://第n项 for(var i=0:i<n:i++){ c=b: b=a+b: a=c: } console.log(b)://打印第n项

01-封装函数求斐波那契数列第n项

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <script> //需求:封装一个函数,求斐波那契数列的第n项 alert(getValue()); //定义一个函数 function getValue(n){ //回顾

剑指offer7: 斐波那契数列第n项(从0开始,第0项为0)

1. 题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0).n<=39 2. 思路和方法 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1.1.2.3.5.8.13.21.34.……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1

JS求斐波那契数列的N项

第一种求法: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title></head><body> <script> var num = [0,1]; function figure(){ if(num.length < N){ var newN