【相当困难】斐波那契系列问题的递归和动态规划-Java:补充题目2
分享一个大牛的人工智能教程。零基础通俗易懂风趣幽默希望你也加入到人工智能的队伍中来请轻击人工智能教程大家好欢迎来到我的网站 人工智能被认为是一种拯救世界、终结世界的技术。毋庸置疑人工智能时代就要来临了科… 继续阅读 前言https://www.captainai.net/troubleshooterpackage live.every.day.ProgrammingDesign.CodingInterviewGuide.RecursionAndDynamicPrograming; /** * 斐波那契系列问题的递归和动态规划 * * 【题目】 * 给定整数N返回斐波那契数列的第N项。 * * 【补充题目】 * 给定整数N代表台阶数一次可以跨个或者个台阶返回有多少种走法。 * * 【补充题目】 * 假设农场中成熟的母牛每年只会生头小母牛并且永远不会死。第一年农场有只成熟的母牛从第二年开始母牛开始生小母牛。 * 每只小母牛年之后成熟又可以生小母牛。给定整数N求出N年后牛的数量。 * * 【要求】 * 对以上所有的问题请实现时间复杂度O(logN)的解法。 * * 【难度】 * 相当困难 * * 【解答】 * 补充问题。 * * 所有的牛都不会死所以第N-1年的牛会毫无损失地活到第N年。同时所有成熟的优缺点都会生出头新的牛那么成熟牛的数量如何 * 估计就是第N-3年的所有牛到第N年肯定都是成熟的牛其间出生的牛肯定都没有成熟。所以C(n)C(n-1)C(n-3)初始项为 * C(1)1C(2)2C(3)3。这个和斐波那契数列又十分类似只不过C(n)依赖C(n-1)和C(n-3)的值而斐波那契数列F(n) * 依赖F(n-1)和F(n-2)的值。同样可以很轻易地写出O(2^N)与O(N)的方法请参看如下代码中的c1和c2方法。 * * O(logN)的方法。C(n)C(n-1)C(n-3)是一个三阶递推数列一定可以用矩阵乘法的形式表示且状态矩阵为3x3的矩阵。 * (Cn,Cn-1,Cn-2)(Cn-1,Cn-2,Cn-3)x|abc,def,ghi| * 把前5项C(1)1C(2)2C(3)3C(4)4C(5)6代入求出状态矩阵 * |abc,def,ghi||110,001,100| * 求矩阵之后当n3时原来的公式可化简为 * (Cn,Cn-1,Cn-2)(C3,C2,C1)x|110,001,100|^n-3(3,2,1)x|110,001,100|^n-3 * 接下来的过程又是利用加速矩阵乘法的方式进行实现具体请参看如下代码中的c3方法。 * * 如果递归式严格符合F(n)axF(n-1)bxF(n-2)...kxF(n-i)那么它就是一个i阶的递推式必然有与ixi的状态矩阵有关的 * 矩阵乘法的表达。一律可以用加速矩阵乘法的动态规划将时间复杂度降为O(logN)。 * * author Created by LiveEveryDay */ public class FibonacciSeries3 { public static int c1(int n) { if (n 1) { return 0; } if (n 1 || n 2 || n 3) { return n; } return c1(n - 1) c1(n - 3); } public static int c2(int n) { if (n 1) { return 0; } if (n 1 || n 2 || n 3) { return n; } int res 3; int pre 2; int prepre 1; int tmp1 0; int tmp2 0; for (int i 4; i n; i) { tmp1 res; tmp2 pre; res res prepre; pre tmp1; prepre tmp2; } return res; } public static int c3(int n) { if (n 1) { return 0; } if (n 1 || n 2 || n 3) { return n; } int[][] base {{1, 1, 0}, {0, 0, 1}, {1, 0, 0}}; int[][] res matrixPower(base, n - 3); return 3 * res[0][0] 2 * res[1][0] res[2][0]; } private static int[][] matrixPower(int[][] m, int p) { int[][] res new int[m.length][m[0].length]; // 先把res设为单位矩阵相当于整数中的 for (int i 0; i res.length; i) { res[i][i] 1; } int[][] tmp m; for (; p ! 0; p 1) { if ((p 1) ! 0) { res multiMatrix(res, tmp); } tmp multiMatrix(tmp, tmp); } return res; } private static int[][] multiMatrix(int[][] m1, int[][] m2) { int[][] res new int[m1.length][m2[0].length]; for (int i 0; i m2[0].length; i) { for (int j 0; j m1.length; j) { for (int k 0; k m2.length; k) { res[i][j] m1[i][k] * m2[k][j]; } } } return res; } public static void main(String[] args) { int n 8; System.out.printf(c1: %d%n, c1(n)); System.out.printf(c2: %d%n, c2(n)); System.out.printf(c3: %d%n, c3(n)); } } // ------ Output ------ /* c1: 19 c2: 19 c3: 19 */
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2558669.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!