简单暴力到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的优化(入门篇)

上篇&#xff0c;我们提到&#xff0c;遇到问题&#xff0c;首先根据定义写出笨方法&#xff0c;找出依赖关系&#xff08;有些题这一步就不太简单&#xff0c;要自己归纳关系&#xff09;&#xff0c;然后进行优化&#xff0c;下面&#xff0c;我们通过几道此方面的经典的&…

简单暴力到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…

c语言简便实现链表增删改查

注&#xff1a;单追求代码简洁&#xff0c;所以写法可能有点不标准。 //第一次拿c开始写数据结构&#xff0c;因为自己写的&#xff0c;追求代码量少&#xff0c;和学院ppt不太一样。有错请指出 #include <stdio.h> #include <stdlib.h> #include <string.h>…

第一次课 课上代码

第一次课内容 学习心态及注意事项 信心 谦虚 脚踏实地 多动手 python简介 代码量少&#xff0c;简介&#xff0c;易上手&#xff0c;语法要求不过于严格&#xff0c; Python 库。 速度慢&#xff0c; 不可加密。 输出、变量、输入 数据类型&#xff1a;整数、浮点数…

计算机考研专业课只考一科的学校汇总

下列学校专业课只考1门 &#xff08;每项科目下的学校均按照最新学科评估结果由高到低进行排名&#xff09; C语言程序设计 1. 湖南大学 计算机技术&软工专硕&#xff08;信息科学与工程学院&#xff09; 2. 中国海洋大学 计算机技术&#xff08;01计算机应用技术方向&am…

数组实现栈

学习了改进&#xff0c;利用define typedef比上次写的链表更容易改变功能&#xff0c;方便维护&#xff0c;代码更健壮。 大佬别嫌弃&#xff0c;萌新总是很笨&#xff0c;用typedef都想不到。 #include<stdio.h> #include<stdbool.h> #define maxsize 10 typede…

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

下面再放三道我比较喜欢的&#xff0c;需要好好写一下的题。 第一题比较水 1. White Cloud is exercising in the playground. White Cloud can walk 1 meters or run k meters per second. Since White Cloud is tired,it cant run for two or more continuous seconds. Whi…

第二次课 课上代码

敲一遍&#xff0c;体会每行代码想表达的意思。 第二讲 创建.py文件 数据类型&#xff1a;布尔(and\or\not) 条件判断语句(if elif else) 列表基础操作&#xff08;特点、创建、增加元素、len()、下标、py切片&#xff09; >>> 5>4 True >>> 4>5 Fa…

第一次课 优秀作业展示

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

dp打开思路:HDU1029 HDU1087 HDU1176 HDU1257 POJ1458(水题不水)

题目&#xff1a;https://vjudge.net/contest/68966#overview HDU - 1029 题意&#xff1a;找出出现次数超过一半的数字 蠢思路&#xff1a;排序找中间 DP&#xff1a;扫一遍一个变量count记录解出现的次数&#xff0c;是当前解就&#xff0c;否则--&#xff0c;count为负就…

dp打开思路2:POJ2533 HDU1114 HDU1260 HDU1160(水题不水)

题目&#xff1a;https://vjudge.net/contest/68966#overview POJ2533 最长上升子序列&#xff0c;很平常的题&#xff0c;但是维持单调队列二分还是值得一贴的&#xff0c;O(nlogn) 关键思想&#xff1a;出现在单调队列里的数都在当前接收的数之前&#xff0c;所以找到最小…

二分查找及一般拓展总结

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

第三次课 课上代码

这次可能比较简短&#xff0c;这样也好&#xff0c;可读性比较强。 别问我为什么&#xff0c;我不会告诉你们我把代码关了的哼哼。 简单复习、注意事项及小知识强调讲解 作业讲解 列表的遍历 For循环&#xff08;这个参考切片&#xff0c;视频有详细讲解&#xff0c;一样的…

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

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

第二次作业 讲解及展示

第二次作业&#xff0c;同学们虽然在认真完成&#xff0c;但是或多或少都出了一些错误&#xff0c;一班张婷&#xff0c;四班武仪人&#xff0c;六班杨泽宇&#xff0c;八班候雯洁&#xff0c;安锦阳&#xff0c;刘净圆&#xff0c;这些同学完成的较为出色&#xff0c;错误较少…

深搜DFS\广搜BFS 图初步入门

首先&#xff0c;不管是BFS还是DFS&#xff0c;由于时间和空间的局限性&#xff0c;它们只能解决数据量比较小的问题。 深搜&#xff0c;顾名思义&#xff0c;它从某个状态开始&#xff0c;不断的转移状态&#xff0c;直到无法转移&#xff0c;然后退回到上一步的状态&#xf…

素数基本(埃氏筛法/线性筛法)

一、检查n是否为素数 最简单思路&#xff1a;所有可能的因数全部试一遍。 int gg(int n) {for(int i2;i<n;i){if((n%i)0)return 0;//有因数就不是素数咯}return 1; } 进一步思考&#xff1a;没必要枚举所有的数&#xff0c;每一个小于n^(1/2)的因数i&#xff0c;一定有一个大…

欧几里得gcd/extend_gcd

正式叙述前还写了一点自己的小感受。 问题&#xff1a;求两个正整数a&#xff0c;b的最大公约数。 大神看来是很简单的问题&#xff0c;但是对于去年夏天刚学python的我来说&#xff0c;这是个很难的问题&#xff0c;还记得当时一晚上睡不着都在想怎么快一点的求出最大公约数…