algorithm-reading

Dynamic Programming - 动态规划

动态规划是一种「分治」的思想,通俗一点来说就是「大事化小,小事化无」的艺术。在将大问题化解为小问题的「分治」过程中,保存对这些小问题已经处理好的结果,并供后面处理更大规模的问题时直接使用这些结果。嗯,感觉讲了和没讲一样,还是不会使用动规的思想解题...

下面看看知乎上的熊大大对动规比较「正经」的描述。

动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。

以上定义言简意赅,可直接用于实战指导,不愧是参加过NOI的。

动规的思想虽然好理解,但是要真正活用起来就需要下点功夫了。建议看看下面知乎上的回答。

动态规划最重要的两个要点:

  1. 状态(状态不太好找,可先从转化方程入手分析)
  2. 状态间的转化方程(从题目的隐含条件出发寻找递推关系)

其他的要点则是如初始化状态的确定(由状态和转化方程得知),需要的结果(状态转移的终点)

动态规划问题中一般从以下四个角度考虑:

  1. 状态(State)
  2. 状态间的转移方程(Function)
  3. 状态的初始化(Initialization)
  4. 返回结果(Answer)

动规适用的情形:

  1. 最大值/最小值
  2. 有无可行解
  3. 求方案个数(如果需要列出所有方案,则一定不是动规,因为全部方案为指数级别复杂度,所有方案需要列出时往往用递归)
  4. 给出的数据不可随便调整位置

单序列(DP_Sequence)

单序列动态规划的状态通常定义为:数组前 i 个位置, 数字, 字母 或者 以第i个为... 返回结果通常为数组的最后一个元素。

双序列(DP_Two_Sequence)

一般有两个数组或者两个字符串,计算其匹配关系。

纸上得来终觉浅,绝知此事要躬行。光说不练假把戏,下面就来几道DP的题练练手。

Reference

  1. 什么是动态规划?动态规划的意义是什么? - 知乎 - 熊大大和王勐的回答值得细看,适合作为动态规划的科普和入门。维基百科上对动态规划的描述感觉太过学术。
  2. 动态规划:从新手到专家 - Topcoder上的一篇译作。