算法学习——动态规划1

众所周知,在面试中最难,也是大公司最容易考的就是动态规划,因此今天打算开撕动态规划,以前只是对于单个的题目知道解法,不过期间一久就忘记了,今天开始要完全的理解方法论再到实践,但愿老天保佑可以一周搞定!面试

一.经过一个小例子了解方法论:算法

一个例子,如上图:编程

求从起点到终点的最短路径:数组

这是一道最基本的动态规划问题,若是不使用动态规划可使用穷举进行求解,路径大概存在2的k次方。利用动态规划求解主要步骤:数据结构

1. 找出规划的初始状态:对此,找出第一个子问题的解从而能够在后面的内容中利用该解来做为后面状态的条件,在这一问题中初始状态就是最邻重点的c点到终点的最短距离。 函数

2. 规划决策路线,这一问题的决策路线是将边界从起点不断的向终点进行移动,以下图。有些问题是从起始状态向终点逐渐向最终状态进行推动,知道最后到达最终学习

状态。优化

2. 转化方程:对于动态规划其求解在于,子子问题->子问题->问题,利用上一状态来求解下一状态,找出先后的关系,最终求解。以下图,该题中的关系很是简单,就是利用前一子问题的解加上当前结点到下一个的最短路线。 设计

3.收敛条件:找出最终状态的终点在哪3d

4.适用的优化原则:一个最优决策序列的任何子序列自己必定是相对于子序列自己的初始和结束状态的最优决策序列。

 

二. 动态规划的设计要素

在第一部分中写了一些关于求解动态规划的我的见解,下面几条是教学视频中总结并列举动态规划基本步骤:

1.问题建模,优化的目标函数是什么?约束条件是什么?

2.划分子问题(边界)

3.子问题和父问题的依赖关系(递推方程)

4.知足优化,判断是否知足优化原则

5.最小子结构,最小函数值是什么,初值是什么?

以上五点能够总结为动态规划的方法论,之后刷题中并不是全部问题均可以根据以上五点进行教科书式的照搬,可是系统的分析动态规划问题,以上五点是对于分析动态规划问题很是重要的步骤,尤为对于初学者来说。以下图,利用一个矩阵链相乘的例子,来利用动态规划的方法来求解此问题。

1.问题建模,优化的目标函数是什么?约束条件是什么?

此问题的目标函数在于找出矩阵相乘找出最小的结果,即:

min = P[0,i]*P[i+1,n]能够获得最小值。

2.划分子问题(边界)

子问题的边界,首先将初始划分边界的i值从0-n所有遍历一遍,找出相乘获得的最小值,此时的i则是划分出来的子区间,再对于[0,i]与[i+1,n]中继续按照以前遍历进行划分,依次类推,直到不可分。找到局部的最小值,从而获得最优解。

3.子问题和父问题的依赖关系(递推方程)

递推方程,以下图:

所谓递推方程最重要的就是一层一层的向最终结果递进,在每一层中遍历全部的元素,找到这一层子问题最优的解,并运用在下一层中。直到达到最终状态,这就是所谓的记忆化编程。 

4.知足优化,判断是否知足优化原则

子问题优化,总体问题也会随之优化,找出的子问题的解也是子过程的最优解。

5.最小子结构,最小函数值是什么,初值是什么?

最小子结构就是第一次对于整个输入的数组进行遍历找出,分隔的最小的点i,这就是初值。 

 

三.动态规划的递归实现:

1.部分伪码

以上为前一题矩阵链相乘的递归实现的伪码:

  1.利用m来记录最终结果的大小q

  2.s来记录划分的位置k

  3-7. 遍历i到k和k+1到j并经过递归调用进行计算,而且不断刷新k和q的值

  8.返回最终结果

2. 有关复杂度:

 3.产生子问题的划分过程:

递归实现的主要的局限在于同一个子问题会被屡次实现,因此其时间复杂度会比较高,解决这一问题能够经过记录子问题结果的方式来实现,下面动态规划的迭代实现。

四.动态规划的迭代实现:

动态规划的迭代实现是后面解题的最经常使用的方式,比起递归的方法,迭代的时间复杂度会小不少,可是须要一个数据结构做为备忘录对每次子问题的结果进行记录,这样能够避免屡次重复计算:

1.迭代计算的关键:

  1.每一个子问题只计算一次

  2.从最小的子问题算起,考虑计算顺序,保证后面的计算过程当中前面计算的结果能够用到。

  3. 用数据结构做为备忘录进行存储

  4.设置标记函数,用标记函数对每一步的解法实施标记,最后获得最终的解法。

 

2. 对于子问题的划分能够递归扩大其长度:

如图,子问题长度从2到8,对于每个长度的划分能够列出全部可能的解

r=2时 存在7种

r=3时 存在6种

r=4时 存在5种

r=5时 存在4钟

以此类推,由此可在每次划定r时找出最小值

 

3.相关伪码 

1.初始化最初子结构

2.从2到n遍历r可能的链长

3-4.在链长固定的状况找出划分的左右边界i和j,i与j的距离始终为r

5. 在备忘录中经过前一子结果得出当前结果,一次划分的初始结果

6. 记录划分位置k

7. 经过点k再在i和j之间进行划分

8-11.找出最优的子划分的位置k以及值t,第八行为状态转移方程

 

4.时间复杂度:

 

 

5.备忘录m,标记表格n 

 

 

五.总结

今天认真系统的学习了一下动态规划,发现之前的学习和刷题都是像走马观花同样,浪费了不少时间,而且不得要领。目前距离彻底理解动态规划还有很长的学习距离,可是打开的系统学习的第一部,真的很重要,下面几条是我结合教学视频上的几点进行总结:

1. 最重要的就是对于动态规划状态的划分,最终状态是什么,从什么状态能够到达最终状态,又从初始状态下怎么达到那一状态。换言之,就是对于子问题的划分,将问题求解转化为多步运算或者多步判断的过程.

2.肯定该问题可否使用动态规划,经过极小值或者极大值做为判断

3.解题的关键在于定义转化方程,例如在最小矩阵链中,一个问题结果能够在若干个子选项中选出一个最小的方案,加上当前数值放在备忘录中

4.利用数据结构创建备忘录,常见数组,矩阵,有时也可能有哈希表的存在

5.有时还须要创建状态转移矩阵,由于可能不只仅是数值,并且还存在数值相对应的状态,例如索引和其余属性须要记录。

 

好长,,,,,第一次写的这么认真,过段时间复习但愿可能看懂,若是一年前开始接触算法题能这样作的话,我可能心在也有工做了,,,,心塞

相关文章
相关标签/搜索