Tribonacci数列前n项和的求解问题
来源:互联网 发布:linux 关闭进程脚本 编辑:程序博客网 时间:2024/05/21 09:31
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次幂,我采用的是二分法。
import java.math.BigDecimal;import java.util.Scanner;public class CopyOfMain2 { public static BigDecimal i1000000007 = new BigDecimal( String.valueOf(1000000007)); //这里定义了四个数,其实是为了下面BigDecimal数组的初始化做准备 public static BigDecimal i3 = new BigDecimal(String.valueOf(3)); public static BigDecimal i2 = new BigDecimal(String.valueOf(2)); public static BigDecimal i1 = new BigDecimal(String.valueOf(1)); public static BigDecimal i0 = new BigDecimal(String.valueOf(0)); public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { long l = scanner.nextLong(); long r = scanner.nextLong(); BigDecimal[] sum = {i0,i0}; sum = Tribonacci(l, r).divideAndRemainder(i1000000007); if(sum[1].longValue()<0)System.out.println(sum[1].add(i1000000007)); else System.out.println(sum[1]); //这是比较笨的方法,用这种遍历的求和方式当然会超时 // for (long i = l; i <= r; i++) { // sum += Tribonacci(i); // } // for(long i =0; i <= 100l; i++){ // sum=Tribonacci(0,i); // System.out.println(i+"---------------------------"+sum % // 1000000007l); // } } } public static BigDecimal Tribonacci(long l, long r) { BigDecimal sum = i0; if (r < 3) { for (long i = l; i <= r; i++) { sum = new BigDecimal(String.valueOf(r - l + 1)); } return sum; } BigDecimal[][] base = { { i1, i1, i0 }, { i1, i0, i1 }, { i1, i0, i0 } }; if (l >= 3l) { BigDecimal[][] res1 = matrixPower(base, l - 3); BigDecimal[][] res = matrixPower(base, r - 2); // long[][] res = muliMatrix(res1,matrixPower(base, r- l+1)); return (res[0][0].subtract(res1[0][0])).multiply(i3) .add((res[1][0].subtract(res1[1][0])).multiply(i2)) .add((res[2][0].subtract(res1[2][0]))); } else { BigDecimal[][] res = matrixPower(base, r - 2); return (res[0][0].multiply(i3).add(res[1][0].multiply(i2)) .add(res[2][0]).subtract(new BigDecimal(String.valueOf(l)))); } } //求Tribonacci数列每一项的方法 // public static long Tribonacci(long n) { // if (n == 0l || n == 1l || n == 2l) { // return 1; // } else if (n == 3l) // return 3; // long[][] base = { { 1l, 1l, 0l}, { 1l, 0l, 1l }, { 1l, 0l, 0l } }; // long sum = 0l; // // long[][] res = matrixPower(base, n - 3l); // // return 3l * res[0][0] + res[1][0] + res[2][0]; // } public static BigDecimal[][] matrixPower(BigDecimal[][] base, long p) { BigDecimal[][] res = new BigDecimal[base.length][base[0].length]; for (int i = 0; i < res.length; i++) { for (int j = 0; j< res[0].length; j++) { if (i == j) { res[i][j] = i1; } else res[i][j] = i0; } } BigDecimal tmp[][] = base; for (; p != 0; p >>= 1) { if ((p & 1) != 0) { res = muliMatrix(res, tmp); } tmp = muliMatrix(tmp, tmp); } return res; } private static BigDecimal[][] muliMatrix(BigDecimal[][] m1, BigDecimal[][] m2) { BigDecimal[][] res = new BigDecimal[m1.length][m2[0].length]; for (int i = 0; i < res.length; i++) { for (int j = 0; j< res[0].length; j++) { res[i][j] = i0; } } for (int i = 0; i < m1.length; i++) { for (int j = 0; j < m2[0].length; j++) { for (int k = 0; k < m2.length; k++) { res[i][j] = res[i][j].add(m1[i][k].multiply(m2[k][j])).divideAndRemainder(i1000000007)[1]; } } } return res; }}
转载请注明网址来源
3 0
- Tribonacci数列前n项和的求解问题
- C语言:求Fibonacci数列的前n项和
- 求数列前n项和实例
- 数列的前N项之和
- 最大子数列和的问题求解
- 求数列的和 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和
- 用递归求数列的前n列的和
- 84.计算数列前n项平方根和
- C++求斐波那切数列及前n项和
- 费波纳切(Fibonacci)数列的前N项和公式(PHP版)三种算法的比较
- JavaScript趣题:Tribonacci数列
- 【C++】斐波那契数列前N项的和递归与非递归算法
- 数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和,要求精度保留2位小数。
- 输出斐波那契数列的前n项
- 斐波那契数列的前n项
- 算法题-数列的前n项之和及扩展
- 常系数线性递推的第n项及前n项和 (Fibonacci数列,矩阵)
- 1242 斐波那契数列的第N项 运用矩阵快速幂来求解斐波那契数列问题
- 【步兵 经验篇】 链式编程
- 《一个定理的诞生》感
- 项目与数据库有关的三种角色
- 只是想删个文件而已~
- 第一篇博客——开始记录自己的CS学习之路
- Tribonacci数列前n项和的求解问题
- JSP网页弹窗代码详解
- [Perl] $SIG{HUP}
- UVA - 624 CD
- 数据库基本操作
- 关于int类型取值范围的计算 以及为何16位int类型范围是- 32768 ~ 32767
- MYSQL中取当前年份的第一天和当前周,月,季度的第一天/最后一天
- 22-reverseString-Leetcode
- 邮票分你一半(nyoj_456)