【斐波那契】原来困扰多年的生兔子问题竟然能够轻松拿捏...万能公式法...

本文主要是介绍【斐波那契】原来困扰多年的生兔子问题竟然能够轻松拿捏...万能公式法...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上篇文章我们讲解了「矩阵快速幂」技巧,通过快速幂极大的优化了 斐波那契数列 的求解问题。并且通过分析知道了 系数矩阵 是解决问题的关键。

本文我们继续深化对于 系数矩阵 的求解,介绍一种通用方法,一举解决所有 斐波那契及变种类型 的问题。

提示: 先看 上篇文章 效果更佳哦~

生兔子问题

有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不会死,问第 N 月有多少对兔子?

这道题不是典型的斐波那契数列么,递推公式为:

这和上道题目一模一样,根本不需要讲解。但是,我们对于本题进行一定的改编,增加点儿难度


假设,现有一对成熟的兔子,新出生的兔子从出生的 第 4 个月 开始每月生一对兔子,问第 N 月有多少对兔子呢?

注意:

  1. 第一月已经有成熟的兔子了,所以从第二月开始就有新的兔子诞生了。
  2. 新出生的兔子三个月后才会生新的兔子。

通过分析不难发现:

因此,递推表达式为:

(如果这样不容易想出来,也可以自己动手列举列举,多写几项就能观察出规律啦)

关系推导

按照 上篇文章 的思路,我们做如下推导:

温馨提示:先看上篇文章更好理解哦~

三个相邻项 写成矩阵形式,由此可以得到关系式:

因此系数矩阵就得到了,后续的求解和上篇文章的简直一模一样了~

-----------------------桥豆麻袋---------------------

有小伙伴说了,这个系数矩阵不太会搞出来啊,那怎么办呢?有什么无脑办法么…哎,还真有!

这就要拿出我们初中就学过的万能的 待定系数法 了。

不就是一个系数矩阵嘛,我直接全设成未知数,一个一个解出来不就行了~

九个未知数,需要九个式子:

虽然看着麻烦,其实解起来也还行吧~哈哈哈,这样我们依然能够得到系数矩阵。

有了系数矩阵之后,就可以将第 n 项化简成只与前 3 项有关的式子。

即系数矩阵的 n-3 次方的第一行与 F3, F2, F1 的内积和。

代码

public static int f(int n) {if (n < 1) {return 0;}if (n == 1 || n == 2 || n == 3) {return n;}int[][] base = { { 1, 0, 1 }, { 1, 0, 0 }, { 0, 1, 0 } };int[][] res = matrixPower(base, n - 3);return 3 * res[0][0] + 2 * res[0][1] + res[0][2];
}private static int[][] matrixPower(int[][] m, int p) {int[][] res = new int[m.length][m[0].length];for (int i = 0; i < res.length; i++) {res[i][i] = 1;}int[][] t = m;for (; p != 0; p >>= 1) {if ((p & 1) != 0) {res = produce(res, t);}t = produce(t, t);}return res;
}private static int[][] produce(int[][] a, int[][] b) {int n = a.length;int m = b[0].length;int k = a[0].length;int[][] ans = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {for (int c = 0; c < k; c++) {ans[i][j] += a[i][c] * b[c][j];}}}return ans;
}

只需在上篇文章代码中,将 f() 函数中初始边界条件、系数矩阵 以及 次方数和返回结果进行修改即可,另外两个函数无需做任何改变(具体细节可以参考 上篇文章 哦~)。

总结

通过本文的探讨,再次验证了 求解系数矩阵 就是解决此类斐波那契递推的关键。我们可以将结论进行适当推广:

当递推式是关于 F(n) 直到 F(n-i) 的,那么就可以将 i 项组合成一个矩阵,进行求解,此时需要构造一个 i*i 的系数矩阵,最终答案与 n-i 次方i 项已知项的内积 有关。


学习到这里,我们就得到了 斐波那契类型题万能解法 了,稍微有点难度哦 ~~~ 点赞、转发让你的小伙伴们一起来学吧!!!

~ 点赞 ~ 关注 ~ 星标 ~ 不迷路 ~!!!

关注回复「ACM紫书」获取 ACM 算法书籍~

这篇关于【斐波那契】原来困扰多年的生兔子问题竟然能够轻松拿捏...万能公式法...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/938652

相关文章

Python轻松实现Word到Markdown的转换

《Python轻松实现Word到Markdown的转换》在文档管理、内容发布等场景中,将Word转换为Markdown格式是常见需求,本文将介绍如何使用FreeSpire.DocforPython实现... 目录一、工具简介二、核心转换实现1. 基础单文件转换2. 批量转换Word文件三、工具特性分析优点局

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

maven异常Invalid bound statement(not found)的问题解决

《maven异常Invalidboundstatement(notfound)的问题解决》本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过... 目录Maven异常:Invalid bound statement (not found) 详解问题描述可

idea粘贴空格时显示NBSP的问题及解决方案

《idea粘贴空格时显示NBSP的问题及解决方案》在IDEA中粘贴代码时出现大量空格占位符NBSP,可以通过取消勾选AdvancedSettings中的相应选项来解决... 目录1、背景介绍2、解决办法3、处理完成总结1、背景介绍python在idehttp://www.chinasem.cna粘贴代码,出

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

SpringSecurity中的跨域问题处理方案

《SpringSecurity中的跨域问题处理方案》本文介绍了跨域资源共享(CORS)技术在JavaEE开发中的应用,详细讲解了CORS的工作原理,包括简单请求和非简单请求的处理方式,本文结合实例代码... 目录1.什么是CORS2.简单请求3.非简单请求4.Spring跨域解决方案4.1.@CrossOr

nacos服务无法注册到nacos服务中心问题及解决

《nacos服务无法注册到nacos服务中心问题及解决》本文详细描述了在Linux服务器上使用Tomcat启动Java程序时,服务无法注册到Nacos的排查过程,通过一系列排查步骤,发现问题出在Tom... 目录简介依赖异常情况排查断点调试原因解决NacosRegisterOnWar结果总结简介1、程序在

解决java.util.RandomAccessSubList cannot be cast to java.util.ArrayList错误的问题

《解决java.util.RandomAccessSubListcannotbecasttojava.util.ArrayList错误的问题》当你尝试将RandomAccessSubList... 目录Java.util.RandomAccessSubList cannot be cast to java.

Apache服务器IP自动跳转域名的问题及解决方案

《Apache服务器IP自动跳转域名的问题及解决方案》本教程将详细介绍如何通过Apache虚拟主机配置实现这一功能,并解决常见问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录​​问题背景​​解决方案​​方法 1:修改 httpd-vhosts.conf(推荐)​​步骤

java反序列化serialVersionUID不一致问题及解决

《java反序列化serialVersionUID不一致问题及解决》文章主要讨论了在Java中序列化和反序列化过程中遇到的问题,特别是当实体类的`serialVersionUID`发生变化或未设置时,... 目录前言一、序列化、反序列化二、解决方法总结前言serialVersionUID变化后,反序列化失