【九章算法】-动态规划

本文是B站课程的一个笔记

https://www.bilibili.com/video/BV1xb411e7ww?from=search&seid=12976071769454038544

动态规划题特点

1.科技公司面试必考

2.题目类型多,没有固定模板

3.难度中上

4.必须掌握

5.时间复杂度比递归好很多

什么题目可以用动态规划来解

1.计数:如:有多少种方式

2.求最值:如:最长上升子序列,最大数字和

3.存在性:如:能不能选出k个数

解题步骤

例题一

https://leetcode-cn.com/problems/coin-change/

第一步:确定状态

状态在动态规划中的作用属于定海神针,简单的说,解动态规划的时候需要开一个数组,状态决定了f[i]和f[i][j]代表什么。

确定状态需要两个意识

1.“最后一步”

虽然我们不知道最优策略是什么,但是最优策略肯定是K枚硬币加起来面值等于27,最后一枚硬币面值是ak,除掉这枚硬币之后面值加起来是27-ak

关键点一:我们不关心前面的k-1枚硬币是怎么拼出27-ak的(可能有一种拼法,可能有很多种)甚至我们都还不知道k是什么ak是什么

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

2.“子问题”

原来我们要求最少多少枚硬币拼出27

现在我们要求最少多少没硬币拼出27-ak

问题的规模减小了,也就是确定了子问题,子问题出来便可以确定状态

状态f(x)=最少用多少枚硬币可以拼出x,原问题是f(27)现在要求f(27-ak)。

如果ak=2,f(27)=f(27-2)+1

如果ak=5,f(27)=f(27-5)+1

如果ak=7,f(27)=f(27-7)+1

所以f(27)=min{f(27-2)+1,f(27-5)+1,f(27-7)+1}

第二步:转移方程

设状态f[x]=最少多少枚硬币拼出x

转移方程:(面试过程中,写对了转移方程就相当于对了一半)

 第三步:初始条件和边界值

边界值:保证数组不要越界。如果不能拼出Y,就定义f[Y]=正无穷

初始条件:由转移方程算不出来,需要手动定义。f[0]=0。

 第四步:计算顺序

本题和大多数动态规划的题目都是从小到大的计算顺序,f[0],f[1],f[2],f[3].....

确定规则:利用转移方程,本题中计算f[x]时,必须要已知f[x-2],f[x-5],f[x-7]所以要先把小的算出来

例题算法实现:https://blog.csdn.net/qq_39328436/article/details/112686479

小结

例题二

第一步:确定状态

“最后一步”:无论机器人用何种方式到达右下角,总有最后挪动的一步,向右或者向下。设右下角的左边为(m-1,n-1),那么前一步只可能有两种情况:(m-1,n-2)或者(m-2,n-1)

“子问题”:假设有X种方式走到(m-1,n-2),有Y种方式走到(m-2,n-1),则最后有X+Y种方式走到(m-1,n-1)

第二步:转移方程

f[i][j]表示走到[i][j]有多少种方式

第三步:初始条件和边界情况

初始条件:f[0][0]=1;

边界情况:f[0][j]=1;f[i][0]=1;

第四步:计算顺序

由转移方程决定,先算第一行,再算第二行....

例题算法实现: https://blog.csdn.net/qq_39328436/article/details/112730774

例题三

第一步:确定状态

“最后一步”:如果青蛙是能跳到最后一块石头n-1,一定是从某一块石头i跳过来的。a[i]代表能够跳跃的最大距离,i和n-1块石头之间的距离是n-1-i,所以最后一步必须满足a[i]>=n-1-i

“子问题”:假设i的上一块石头是j,则必须满足a[j]>=j-i

第二步:转移方程

第三步:初始条件和边界情况

初始条件:f[0]=true.

边界情况:不会越界

第四步:计算顺序

由转移方程决定,从小到大算

例题算法实现: https://blog.csdn.net/qq_39328436/article/details/113093715

作业题

第一步:确定状态

“最后一步”:由于有负数存在,所以会使得最小的乘积变成最大,最大的乘积变成最小

最大的乘积可能来自于三种情况:

1.最小的负数乘积*当前的负数=最大的正数乘积

2.最大的正数乘积*当前的正数=最大的正数乘积

3.当前的数独立构成序列。

“子问题”:求fmax[i] fmin[i]

用fmax[i]表示以i为结尾的序列构成的最大乘积

用fmin[i]表示以i为结尾的徐柳构成的最小乘积

第二步:转移方程

第三步:初始条件和边界情况

初始条件:

 maxF[0]=nums[0];

minF[0]=nums[0];

边界情况:

第四步:计算顺序

由转移方程决定,从小到大算

例题算法实现:https://blog.csdn.net/qq_39328436/article/details/113095431

猜你喜欢

转载自blog.csdn.net/qq_39328436/article/details/112686337