每周一刷——从斐波那契数列到动态规划
- 一写在前面的话
- 二普通版
- 三改进版
- 四动态规划版
一、写在前面的话
在csdn上看到一篇博客,博客的内容有有关图像方面的paper,有有关机器学习的理论推导和python实践,文风简洁而不拖沓,非常喜欢,仿佛找到了同类,翻到“about me”以及一些求职的博文,方向选择之困惑,在求学期间学习方法之反思(实践、实践、还是实践)。仿佛看到了自己,看到了自己的明天,这位博主对算法之深刻,找工作之路尚感艰难,何况我呢。顿感企业要求之高(基础之看重),算法学习之路艰辛,学习之法之重要。这里,今天,特开一个算法系列,在基于数学的机器学习算法之外,重新整理更为基础的数据结构与算法。绳锯木断水滴石穿,星星之火可以燎原,为以后的求职之路打下基础。
既然是写在前面的话,不妨订立几条标准。
更新的频次上,≥ \geq2篇/周;
不简单地粘贴代码,必须凝结自己的思考;
透过实现的技巧看算法的本质,通过代码理解基本概念;
……
这个系列主要参考的书有:
挑战程序设计竞赛
剑指ofter
二、普通版
首先以递归的形式定义Fibonacci数列的第N N项F(N) F(N)的计算公式:
F(n) = \left\{ \begin{aligned} & n \qquad \qquad \qquad \qquad \quad n \leq 1\\ & F(n-1)+F(n-2) \quad n \geq 2 \end{aligned} \right.
根据此递归形式的定义,可得出二分递归版fib(n)
算法:
// sizeof(__int64) == 8
// sizeof(__int64) == sizeof(long long)
// 注意斐波那契数列的增长速度是很快的,fib(40)的值已超过10^9
__int64 fib(unsigned n)
{if (n <= 1)return n;elsereturn fib(n-1) + fib(n-2);
}
简单的if-else
语句又可进一步简化为三目运算符:
__int64 fib(unsigned n)
{return (n <= 1) ? __int64(n) : fib(n-1) + fib(n-2);
}
三、改进版
虽然定义、形式和实现上都十分简单和便于理解,二分递归版却存在大量重复计算
的问题。以F(10) F(10)的递归计算为例考察二分递归版的重复计算问题,如图示:
解决的思路便是考虑如何利用已计算的中间值来计算当前要计算的值,剑指offer给出的解决方案是,完全不在沿用传统的递归
计算(从后向前的)方式,而是采用顺序的循环
的向后计算方式,为了方便计算需引入两个中间变量
__int64 fibNMinus1, fibNMinus2;
分别表示F(n−1) F(n-1)、F(n−2) F(n-2)来记录每一次参与循环计算的第一个加数和第二个加数。代码如下:
__int64 fib(unsigned n)
{if (n <= 1)return n;__int64 fibNMinus1 = 1;__int64 fibNMinus2 = 0;__int64 fibN = 0;for (unsigned i = 2; i <= n; ++i){fibN = fibNMinus1 + fibNMinus2;fibNMinus2 = fibNMinus1;fibNMinus1 = fibN;}return fbN;
}
四、动态规划版
剑指offer提供的替代方案仍然具有一定的技巧性,所谓技巧性也即不可复制性,这里提供一种通用的解决方案,所谓的通用,是因为它利用了一种算法思想:动态规划(DP:dynamic programming),这里抛开动态规划严格且抽象的定义,我们从它的实现方式入手,也即记录结果再利用
,我们来看动态规划版本的计算方法:
long long memo[N+1]; // 全局变量,初始化为0
long long fib(unsigned n)
{if (n <= 1)return n;if (memo[n]) return memo[n];elsereturn memo[n] = fib(n-1) + fib(n-2);
}
这里看似好像仍然是之前的递归形式相同,然而,通过查看其递归调用的流程可以发现,分支的右侧,已在左侧计算出且保存在mem[n]中,
。
这篇博客的最终目的是为了引出动态规划的算法思想,自然想要把握动态规划的精髓,是完全不够的,会在以后的文章中反复思考和探索动态规划。
每周一刷——从斐波那契数列到动态规划相关推荐
- 青蛙跳台阶问题(斐波拉契数列、动态规划)
青蛙跳台阶问题 题目描述: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶.求该青蛙跳上一个 n 级的台阶总共有多少种跳法. 答案需要取模 1e9+7(1000000007),如计算初始结果为:10 ...
- 斐波那契数列与黄金分割比以及矩阵形式推导
数学上,斐波那契数列以递归的形式进行定义: F 0 =0F 1 =1F n =F n−1 +F n−2 \begin{split} &F_0=0\\ &F_1=1\\ & ...
- 深入剖析斐波拉契数列
深入剖析斐波拉契数列 前言 动态规划作为一种非常经典的一类算法,不仅在解决实际问题当中有很多实际的应用,同时通常也是面试的一个重点.本篇文章一步步剖析动态规划的基本原理,通过斐波拉契数列问题(优化时间 ...
- NO7、斐波那契数列(easy不需再刷)
7.斐波那契数列 easy不需再刷 示例1 输入 4 返回值 3 1.采用三个元素保存数组即可 int Fibonacci(int n) {if (n == 1 || n == 2) return 1 ...
- 牛客网刷题java之(斐波那契数列)一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 分析: 对于本题,前提只有 一次 1阶或者2阶的跳法. a.如果两种跳法, ...
- 【刷题笔记4】木棍组成三角形问题(斐波那契数列)
题目 在迷迷糊糊的大草原上, 小红捡到了n根木棍, 第i根木棍的长度为i,小红现在很开心. 想选出其中的三根木棍组成美丽的三角形.但是小明想捉弄小红, 想去掉一些木棍, 使得小红任意选三根木棍都不能组 ...
- 剑指 offer 面试题精选图解 10-I.斐波那契数列
大家好,我是程序员吴师兄,欢迎来到图解剑指 Offer 专栏,在这个专栏里我将和大家一起学习如何用合理的思维来思考.解题.写代码. 今天分享的题目来源于 LeetCode 上的剑指 Offer 系列 ...
- Python程序模拟手工推算考虑兔子寿命的斐波那契数列
开学第一课:拜托,一定不要这样问Python问题 中国大学MOOC"Python程序设计基础"免费学习地址 推荐图书: <Python程序设计(第3版)>,(ISBN: ...
- HDU 4549 M斐波那契数列(矩阵快速幂费马小定理)
ps:今天和战友聊到矩阵快速幂,想到前几天学长推荐去刷矩阵专题,挑了其中唯一一道中文题,没想到越过山却被河挡住去路... 题目链接:[kuangbin带你飞]专题十九 矩阵 R - M斐波那契数列 T ...
最新文章
- 30秒或更短的时间内弄懂的有用CSS代码片段
- 高斯-赛德尔迭代法简介
- 爬虫学习笔记(三)requests模块使用
- QT的QMutex类的使用
- 单链表遍历_单链表及其遍历实现的基本操作
- php防止跨域提交,PHP防止跨域提交表单的简单示例
- 后台备份20080917
- Java抓取电脑屏幕
- Day11 - 使用正则表达式
- 列转行 带逗号_Excel 统计压岁钱?按逗号拆分单元格且纵向排列,分离中文和数字...
- CentOS修改tomcat端口
- 报修管理系统微信小程序源码
- 2022 CCF国际AIOps挑战赛决赛暨AIOps研讨会成功举办
- 【R语言】【可视化】 之 维恩图
- lepus安装部署详解
- HBuilder X 中使用模拟器进行App开发
- Silvaco学习笔记(六)毕设相关
- 计算机组成-无符号数乘法
- 淘东电商项目(47) -商品搜索服务功能的实现(集成拼音分词器)
- PMP 考试是一个骗局吗?
热门文章
- spark算子的分类
- html中可以编辑的文本,用BeautifulSoup编辑html中的文本
- oracle sequence 应用,oracle应用之使用sequence批量写数据
- 剑指offer面试题24. 反转链表(双指针)
- python爬虫(四)_urllib2库的基本使用
- Ceres配置(vs2013+Win10)
- 生产阶段Webpack打包【基础打包】
- 设计模式-单例模式扩展(程序员学习之路-架构之路)
- 男生看女生叫审美,女生看男生叫好色之新解
- MVC3 Razor 语法检查 -(转)