简单暴力到dp的优化(萌新篇)

想写一系列文章,总结一些题目,看看解决问题、优化方法的过程到底是什么样子的。

 

系列问题一:斐波那契数列问题

在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)根据定义,前十项为1, 1, 2, 3, 5, 8, 13, 21, 34, 55

问题一:

给定一个正整数n,求出斐波那契数列第n项(这时n较小)

解法一:最笨,效率最低,暴力递归,完全是抄定义。请看代码

def f0(n):if n==1 or n==2:return 1return f(n-1)+f(n-2)

 

分析一下,为什么说递归效率很低呢?咱们来试着运行一下就知道了

 

比如想求f(10),计算机里怎么运行的?

 

每次要计算的函数量都是指数型增长,时间复杂度O(2^(N/2))<=T(N)<=O(2^N),效率很低。效率低的原因是,进行了大量重复计算,比如图中的f(8),f(7).....等等,你会发现f(8)其实早就算过了,但是你后来又要算一遍。

如果我们把计算的结果全都保存下来,按照一定的顺序推出n项,就可以提升效率, 斐波那契(所有的一维)的顺序已经很明显了,就是依次往下求。。

优化1

def f1(n):if n==1 or n==2:return 1l=[0]*nl[0],l[1]=1,1for i in range(2,n):l[i]=l[i-1]+l[i-2]return l[-1]

 

时间复杂度o(n),依次往下打表就行,空间o(n).

继续优化:既然只求第n项,而斐波那契又严格依赖前两项,那我们何必记录那么多值呢?记录前两项就行了

 

优化2

def f2(n):a,b=1,1for i in range(n-1):a,b=b,a+breturn a

此次优化做到了时间o(n),空间o(1)

附:这道题掌握到这里就可以了,但是其实有时间o(log2n)的方法

 

优化三:

学习过线性代数的同学们能够理解:

 

结合快速幂算法,我们可以在o(log2n)内求出某个对象的n次幂。(在其它专题详细讲解)

注意:只有递归式不变,才可以用矩阵+快速幂的方法。

注:优化三可能只有在面试上或竞赛中用,当然,快速幂还是要掌握的。

 

经过这个最简单的斐波那契,大家有没有一点感觉了?

好,我们继续往下走

(补充:pat、蓝桥杯原题,让求到一万多位,结果模一个数。

可以每个结果都对这个数取模,否则爆内存,另:对于有多组输入并且所求结果类似的题,可以先求出所有结果存起来,然后直接接受每一个元素,在表中查找相应答案)

 

问题二:

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

依旧是找递推关系,分析:跳一阶,就一种方法,跳两阶,它可以一次跳两个,也可以一个一个跳,所以有两种,三个及三个以上,假设为n阶,青蛙可以是跳一阶来到这里,或者跳两阶来到这里,只有这两种方法。它跳一阶来到这里,说明它上一次跳到n-1阶,同理,它也可以从n-2跳过来,f(n)为跳到n的方法数,所以,f(n)=f(n-1)+f(n-2)

和上题的优化二类似。

因为递推式没变过,所以可以用优化三

 

问题三:

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?提示,大矩形看做是长度吧

请读者自己先思考一下吧。。。仔细看题。。仔细思考

如果n是1,只有一种,竖着放呗;n是2,两种:

n等于3,三种:

 

题意应该理解了吧?

读到这里,你们应该能很快想到,依旧是斐波那契式递归啊。

对于n>=3:怎么能覆盖到三?只有两种办法,从n-1的地方竖着放了一块,或者从n-2的位置横着放了两块呗。

和问题二的代码都不用变。

 

问题四:

给定一个由0-9组成的字符串,1可以转化成A,2可以转化成B。依此类推。。25可以转化成Y,26可以转化成z,给一个字符串,返回能转化的字母串的有几种?

比如:123,可以转化成

1 2 3变成ABC,

12 3变成LC,

1 23变成AW,三种,返回三,

99999,就一种:iiiii,返回一。

分析:求i位置及之前字符能转化多少种。

两种转化方法,一,字符i自己转换成自己对应的字母,二,和前面那个数组成两位数,然后转换成对应的字母

假设遍历到i位置,判断i-1位置和i位置组成的两位数是否大于26,大于就没有第二种方法,f(i)=f(i-1),想反,等于f(i-1)+f(i-2)

注意:递归式不确定,不能用矩阵快速幂

 

(这几个题放到这里就是为了锻炼找递归关系的能力,不要只会那个烂大街的斐波那契)

 

'''
斐波那契问题:
斐波纳契数列以如下被以递归的方法定义:
F(1)=1
F(2)=1
F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
'''
#暴力抄定义,过多重复计算
def f0(n):if n==1 or n==2:return 1return f(n-1)+f(n-2)
#记录结果后依次递推的优化,时间O(N)
def f1(n):if n==1 or n==2:return 1l=[0]*nl[0],l[1]=1,1for i in range(2,n):l[i]=l[i-1]+l[i-2]return l[-1]
#既然严格依赖前两项,不必记录每一个结果,优化空间到O(1)
def f2(n):a,b=1,1for i in range(n-1):a,b=b,a+breturn a

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445671.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode - Medium - 114. Flatten Binary Tree to Linked List

Topic TreeDepth-first Search Description https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ Given the root of a binary tree, flatten the tree into a “linked list”: The “linked list” should use the same TreeNode class where the right…

简单暴力到dp的优化(初级篇)

一、一维非脑残 1 一个只包含A、B和C的字符串&#xff0c;如果存在某一段长度为3的连续子串中恰好A、B和C各有一个&#xff0c;那么这个字符串就是纯净的&#xff0c;否则这个字符串就是暗黑的。例如&#xff1a;BAACAACCBAAA 连续子串"CBA"中包含了A,B,C各一个&am…

ccpc河北大学生程序设计竞赛dp小总结

近期题目来自校赛&#xff0c;赛前训练&#xff0c;省赛热身&#xff0c;河北ccpc正式比赛。 题目一&#xff1a; 题目描述&#xff1a; 由于第m个台阶上有好吃的薯条&#xff0c;所以薯片现在要爬一段m阶的楼梯. 薯片每步最多能爬k个阶梯&#xff0c;但是每到了第i个台阶&a…

第一次课 优秀作业展示

18级河北师大软件编程训练 很多同学非常认真的完成了作业&#xff0c;这里选出比较优秀的作业展示出来。 注&#xff1a;展示顺序不是排名 为了尊重同学们的劳动成果&#xff0c;并没有要代码&#xff0c;只是截图展示。 范天祚 &#xff08;傻兔子&#xff09; 熊静祎&…

二分查找及一般拓展总结

二分-不止是查找哦 二分过程&#xff1a;首先&#xff0c;假设表中元素是按升序排列&#xff0c;将表中间位置记录的关键字与查找关键字比较&#xff0c;如果两者相等&#xff0c;则查找成功&#xff1b;否则利用中间位置记录将表分成前、后两个子表&#xff0c;如果中间位置记…

排序算法基本介绍及python实现(含详细注释)

对数组排序可以说是编程基础中的基础&#xff0c;本文对八种排序方法做简要介绍并用python实现。 代码中注释很全&#xff0c;适合复习和萌新学习。这是刚入学自己写的&#xff0c;可能难免比不上标准的写法&#xff0c;但是懒得改了。 文末会放和排序相关的基本拓展总结链接…

二叉搜索树实现

本文给出二叉搜索树介绍和实现 首先说它的性质&#xff1a;所有的节点都满足&#xff0c;左子树上所有的节点都比自己小&#xff0c;右边的都比自己大。 那这个结构有什么有用呢&#xff1f; 首先可以快速二分查找。还可以中序遍历得到升序序列&#xff0c;等等。。。 基本操…

快排-荷兰国旗

在使用partition-exchange排序算法时&#xff0c;如快速排序算法&#xff0c;我们会遇到一些问题&#xff0c;比如重复元素太多&#xff0c;降低了效率&#xff0c;在每次递归中&#xff0c;左边部分是空的(没有元素比关键元素小)&#xff0c;而右边部分只能一个一个递减移动。…

时间空间复杂度概述

找个时间写一写时间复杂度和一些问题分类&#xff0c;也普及一下这方面知识。 如何衡量一个算法好坏 很显然&#xff0c;最重要的两个指标&#xff1a;需要多久可以解决问题、解决问题耗费了多少资源 那我们首先说第一个问题&#xff0c;要多长时间来解决某个问题。那我们可…

二叉树遍历算法总结

文章目录前提要素深度优先搜索DFS经典遍历算法前序遍历递归版迭代版中序遍历递归版迭代版后序遍历递归版迭代版Morris遍历算法中序遍历前序遍历后序遍历广度优先搜索BFS按层遍历参考资料前提要素 本文代码用Java实现。 //二叉树节点结构 public static class TreeNode {publi…

线段树简单实现

首先&#xff0c;线段树是一棵满二叉树。&#xff08;每个节点要么有两个孩子&#xff0c;要么是深度相同的叶子节点&#xff09; 每个节点维护某个区间&#xff0c;根维护所有的。 如图&#xff0c;区间是二分父的区间。 当有n个元素&#xff0c;初始化需要o(n)时间&#xf…

树状数组实现

树状数组能够完成如下操作&#xff1a; 给一个序列a0-an 计算前i项和 对某个值加x 时间o(logn) 注意&#xff1a;有人觉得前缀和就行了&#xff0c;但是你还要维护啊&#xff0c;改变某个值&#xff0c;一个一个改变前缀和就是o(n)了。 线段树树状数组的题就是这样&#x…

KMP子字符串匹配算法学习笔记

文章目录学习资源什么是KMP什么是前缀表为什么一定要用前缀表如何计算前缀表前缀表有什么问题使用next数组来匹配放码过来构造next数组一、初始化二、处理前后缀不相同的情况三、处理前后缀相同的情况使用next数组来做匹配代码总览测试代码时间复杂度分析学习资源 字符串&…

内存分区

之前一直比较懵&#xff0c;想想还是单独写一个短篇来记录吧 一般内存主要分为&#xff1a;代码区、常量区、静态区&#xff08;全局区&#xff09;、堆区、栈区这几个区域。 代码区&#xff1a;存放程序的代码&#xff0c;即CPU执行的机器指令&#xff0c;并且是只读的。 常…

数据结构课上笔记5

介绍了链表和基本操作 用一组物理位置任意的存储单元来存放线性表的数据元素。 这组存储单元既可以是连续的&#xff0c;也可以是不连续的&#xff0c;甚至是零散分布在内存中的任意位置上的。因此&#xff0c;链表中元素的逻辑次序和 物理次序不一定相同。 定义&#xff1a; …

Java设计模式(2 / 23):观察者模式

定义 观察者&#xff08;Observer&#xff09;模式定义了对象之间的一对多依赖&#xff0c;这样一来&#xff0c;当一个对象改变状态时&#xff0c;它的所有依赖者都会收到通知并自动更新。 OO设计原则&#xff1a;为了交互对象之间的松耦合设计而努力。 案例&#xff1a;气…

二叉树概述

各种实现和应用以后放链接 一、二叉树的基本概念 二叉树&#xff1a;二叉树是每个节点最多有两个子树的树结构。 根节点&#xff1a;一棵树最上面的节点称为根节点。 父节点、子节点&#xff1a;如果一个节点下面连接多个节点&#xff0c;那么该节点称为父节点&#xff0c;它…

Java设计模式(1 / 23):策略模式

定义 策略&#xff08;Strategy&#xff09;模式定义了算法族&#xff0c;分别封装起来&#xff0c;让它们之间可以互相替换 &#xff0c;此模式让算法的变化独立于使用算法的客户。 案例&#xff1a;模拟鸭子应用 一开始 新需求&#xff1a;模拟程序需要会飞的鸭子 在父类新…

Java设计模式(3 / 23):装饰者模式

文章目录定义案例1&#xff1a;三点几啦首次尝试再次尝试设计原则&#xff1a;类应该对扩展开放&#xff0c;对修改关闭尝用装饰者模式装饰者模式特征本例的类图放码过来饮料类HouseBlendDarkRoastEspressoDecaf调料装饰类MilkMochaSoyWhip运行测试类案例2&#xff1a;编写自己…