一、和分治法、贪心法的比较
分治法中各子问题是相互独立的,即它们不包含公共子问题。贪心法的当前选择不能依赖将来所作的选择和子问题的解。它们的不足是:如果各子问题不是相互独立的,则分治法会重复求解公共子问题;如果当前选择可能要依赖子问题的解时,则难以通过局部的贪心策略求得全局最优解。
二、动态规划求解的问题
动态规划求解的问题往往是最优化问题,而且要具备两个重要性质:最优子结构性质和子问题重叠性质。
最优子结构性质是指原问题的最优解包含着其子问题的最优解。可以通过反证法来证明。
子问题重叠性质是指原问题分解得到的各子问题不是相互独立的,而是包含公共的子问题。
三、动态规划的具体实现
通常动态规划可以通过两种方式实现:递推和记忆化搜索。
递推是采用自底向上的方式,通过枚举阶段、状态和决策来计算状态转移方程,递推求得原问题的最优解,这种实现方式的时空代价相对较小,因而被普遍采用。
记忆化搜索是直接根据状态转移方程的递归定义,以自顶向下的方式递归求得原问题的最优解,并在初次求解一个子问题后将其最优解记录下来,再次求解该子问题时只需查看记录结果即可,从而避免重复求解想通子问题。记忆化搜索的优点是可以避免求解无用子问题、可以自顶向下剪枝以及编程实现简单等,其缺点是无法利用一些特定的优化技巧来降低时空代价。
对于一个具体问题,通常按照下面步骤设计动态规划算法:
(1) 找出最优解的性质,并刻画其结构特征。
(2) 递归定义最优解。
(3) 以自底向上的递推方式或自顶向下的记忆化搜索方式计算最优值。
(4) 根据计算最优值得到的信息,构造一个最优解。
其中步骤(1)~(3)是动态规划算法的基本步骤,如果只需要最优值,(4)可省略,如果还需要最优解,则必须执行步骤(4),且步骤(3)中需要记录更多的信息。
四、动态规划算法的复杂度
动态规划算法仍然存在冗余,主要有求解子问题和引用了对结果无意义的子问题等。
动态规划算法的时间复杂度可按下式进行计算:
时间复杂度 = 状态总数 × 每个状态转移的状态数 × 每次状态转移的时间
这三个因素之间不是相互独立的,而是相互联系的。