动态规划 规划人生

一,介绍

1,动态规划在数学,计算机科学和经济学等领域中极为常见,是一种通过把原问题分解为相对简单的子问题的方式来求解的方法。

2,动态规划是近几年科技公司面试的必考算法,题目类型多,没有固定模板,难度大多属于中上,根据面试统计结果,一般失败的面试都与动态规划有关。但是动态分析并不可怕,可怕的是你的内心,不要遇到这种题就绕道而行。其实是有规律可行的,我们下面来通过几个经典例子,掌握其中的思想,举一反三!

eg1:

你有三种硬币,分别面值2元,5元和7元,每种硬币都有足够多。买一本书需要27元,如何用最少的硬币组合正好还清,不需要对方找钱。

(1)按照常理,最少的硬币组合 即尽量用面值大的硬币

  • 7+7+7=21
  • 21+5=26
  • 呃。。。

(2) 改算法:尽量用大的硬币,最后如果可以用一种硬币付清就行。

  • 7+7+7=21
  • 21+2+2+2=27
  • 6枚硬币,应该对了吧。。。

正确答案是 7+5+5+5+5=27
5枚硬币

不可思议吧,哈哈哈,别吃惊,我来告诉你为什么** _ **

动态规划组成部分一:确定状态

(1)状态太动态规划中作用属于定海神针( important!)

(2)简单地说,解动态规划的时候,需要开一个数组,数组的每一个元素构成的 f[i][j] 表示什么

类似于数学题中,x,y,z代表什么

(3)确定状态需要两个意识
<1>最后一步
<2>子问题

<1>“最后一步”
虽然我们也不知道最优策略是什么,但是最优策略肯定是K枚硬币a1,a2,…,ak面值和为27
所以一定有一枚最后的硬币:ak
除去这一枚硬币,前面硬币的面值和加起来是27-ak

在这里有两个关键点:
(1)关键点一:
我们不关心前面的k-1枚硬币怎么拼出27-ak的(可能有1种拼法,可能有100种),而且我们学长甚至不知道ak和k,但是我们已经确定前面的硬币拼出了27-ak

(2)关键点二:
因为是最优策略,所以拼出27-ak的硬币数一定是最少的,否则就不是最优策略了。

<2>“子问题”
(1)所以我们现在就需要求:最少用多少枚硬币可以拼出27-ak

(2)原问题是最少用多少枚硬币拼出27

(3)我们把原问题转化为了规模更小的子问题 :27-ak

(4)为了简化定义,我们设状态 f(X)=最少用多少枚硬币拼出X

Wait!!!我们还不知道最后那枚硬币ak是多少
莫慌,继续分析。

最后那枚硬币ak只可能是2,5,7
<1>如果ak=2,f(27)=f(27-2)+1
<2>如果ak=5,f(27)=f(27-5)+1
<3>如果ak=7,f(27)=f(27-7)+1
除此之外,木有其他的可能了
需要求最少的硬币数,所以:
f(27)=min{f(27-2)+1,f(27-5)+1,f(27-7)+1}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

同理f(27-7)+1

如果用递归法解题,我们画图表示一下(字有点丑,嘻嘻)

在这里插入图片描述
可以发现,递归解题时存在的问题
(1)做了很多重复的计算,效率低下
(2)如何避免
(3)将计算结果保存起来,并改变计算顺序

动态规划组成部分二:转移方程

(1)转移方程在面试的时候至关重要,当然也是解决问题很重要的一部分
(2)对于任意X,
f[X]=min{f[X-2]+1,f[X-5]+1,f[X-7]+1}

动态规划组成部分三:初始条件和边界情况
(1)f[X]=min{f[X-2]+1,f[X-5]+1,f[X-7]+1}
(2)两个问题:
<1> X-2, X-5, X-7小于0怎么办?
<2>什么时候停止?
(3)如果拼不出Y,就定义f[Y]=正无穷大
eg:f[-1]=f[-2]=…=正无穷大
(4)所以f[1]=min ( f[-1]+1 , f[-4]+1 , f[-6]+1)=正无穷大,表示拼不出来1
(5)初始条件:f[0] = 0

动态规划组成部分四:计算顺序

计算顺序时根据实际情况来定的
例如本题就是要先算小的,才能算出大的
即先算f[1],f[2]…f[27]

f[X]=min{f[X-2]+1,f[X-5]+1,f[X-7]+1}
对于这个式子,如果把右侧的减号改成加号,则应该先算大的
(1)每一步尝试三种硬币,一共27步
(2)与递归算法相比,木有任何重复计算
(3)算法时间复杂度(即需要进行的步数):27*3

eg2:

给定m行n列的网络,有一个机器人从左上角(0,0)出发,每一步可以向下或者向右走一步
问有多少种不同的方式走到右下角

在这里插入图片描述

画得好丑,哈哈哈~
【分析】
动态规划组成部分一:确定状态

  • 最后一步:无论机器人用何种方式到达右下角,总有最后挪动的一步

  • 右下角坐标设为(m-1,n-1)

  • 那么前一步机器人一定是在(m-2,m-1)或者(m-1,n-2)

  • 子问题

  • 如果机器人有x种方式从左上角走到(m-2,n-1),有y种方式从左上角走到(m-1,n-2),则机器人有x+y种方式走到(m-1,n-1)

  • 问题转化:机器人有多少种方式从左上角走到(m-2,n-1)和(m-1,n-2)

  • 状态:设f[i][j]为机器人有多少种方式从左上角走到(i,j)

在这里插入图片描述
*
动态规划组成部分二:转移方程

f[i][j]=f[i-1][j]+f[i][j-1]
f[i][j] , f[i-1][j] , f[i][j-1]代表的意思如上解释

动态规划组成部分三:初始条件和边界情况

初始条件:f[0][0]=1,因为机器人只有一种方式到左上角
边界情况:i=0或者j=0,则前一步只能有一个方向过来:f[i][j]=1

动态规划组成部分四:计算顺序
f[0][0]=1
计算第0行:f[0][0],f[0][1]…f[0][n-1]
计算第1行:f[1][0],f[1][1]…f[1][n-1]

计算第m-1行:f[1][0],f[m-1][1]…f[m-1][n-1]
答案是f[m-1][n-1]
时间复杂度(计算步数):O(MN)
空间复杂度(数组大小):O(MN)

《小结》

动态规划组成部分
1,确定状态
<1>研究最优策略的最后一步
<2>化为子问题

2,转移方程
根据子问题定义直接得到

3,初始条件和边界问题
细心,考虑周全

4,计算顺序
利用之前的计算结果

动态规划题目的特点
在这里插入图片描述
【寄语】世界的路,为自己改变;人生的路,为自己改变,做好自己就是最大的成功。希望读到这篇博文的你,能够有梦可逐!

这篇博文是我看了几个b站视频,总结感悟出来的,有什么不妥之处,欢迎大家提出!

私信,关注,评论都欢迎呀* ~ *

发布了22 篇原创文章 · 获赞 19 · 访问量 5891

猜你喜欢

转载自blog.csdn.net/qq_45748475/article/details/104348788
今日推荐