动态规划习题精讲
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
信息学竞赛中的动态规划专题
哈尔滨工业大学周谷越
【关键字】
动态规划动机状态典型题目辅助方法优化方法
【摘要】
本文针对信息学竞赛(面向中学生的Noi以及面向大学生的ACM/ICPC)中的动态规划算法,从动机入手,讨论了动态规划的基本思想和常见应用方法。通过一些常见的经典题目来归纳动态规划的一般作法并从理论上加以分析和说明。并介绍了一些解决动态规划问题时的一些辅助技巧和优化方法。纵观全文可知,动态规划的关键在于把握本质思想的基础上灵活运用。
【目录】
1.动态规划的动机和基本思想
1.1.解决重复子问题
1.2.解决复杂贪心问题
2.动态规划状态的划分方法
2.1.一维状态划分
2.2.二维状态划分
2.3.树型状态划分
3.动态规划的辅助与优化方法
3.1.常见辅助方法
3.2.常见优化方法
4.近年来Noi动态规划题目分析
4.1 Noi2005瑰丽华尔兹
4.2 Noi2005聪聪与可可
4.3 Noi2006网络收费
4.4 Noi2006千年虫
附录参考书籍与相关材料
1.动态规划的动机和基本思想
首先声明,这里所说的动态规划的动机是从竞赛角度出发的动机。
1.1 解决重复子问题
对于很多问题,我们利用分治的思想,可以把大问题分解成若干小问题,然后再把各个小问题的答案组合起来,得到大问题的解答。这类问题的共同点是小问题和大问题的本质相同。很多分治法可以解决的问题(如quick_sort,hanoi_tower等)都是把大问题化成2个以内的不相重复的小问题,解决的问题数量即为∑(log2n / k)。而考虑下面这个问题:
USACO 1.4.3 Number Triangles
http://122.139.62.222/problem.php?id=1417
【题目描述】
考虑在下面被显示的数字金字塔。
写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。每一步可以走到左下方的点也可以到达右下方的点。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 1
在上面的样例中,从7到3到8到7到5的路径产生了最大和:30。
【输入格式】
第一个行包含R(1<= R<=1000) ,表示行的数目。后面每行为这个数字金字塔特定行包含的整数。所有的被供应的整数是非负的且不大于100。
【输出格式】
单独的一行包含那个可能得到的最大的和。
【样例输入】
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 1
【样例输出】
30
显然,我们同样可以把大问题化成小问题来解决。如样例中最底层的6就可以从次底层
的两个4走来,假设分别知道走到次底层的两个4的最优解,那么取其中较大的加上6就是走到最底层的6时的最优解。然而次底层的两个4还可以走向最底层的2和1,这样就产生了重复的子问题。动态规划的第一类动机就是为了要避免这种重复运算。
事实上,子问题的个数是确定的,只要我们能够把已经计算过的子问题记录下来,再下次需要时直接使用,便可以大大提高程序的效率。
下面介绍一下动态规划的相关概念。首先动态规划是来解决最优化问题的,再进一步说就是解决最优化问题中的多阶段决策问题。
以下是动态的定义内容,在各种基础书籍上都有相关讲解,在此仅列出,不做累述。
状态(State):表示事物的性质,是描述动态规划中的单元的量。
阶段(Stage):阶段是一些性质相近的状态集合。
决策(Decision):每个阶段做出的某种选择性行动,是程序所需要完成的选择。
状态转移方程(Equal):是前一个阶段的状态转移到后一个的状态的演变规律,是关于两个相邻阶段状态变化的方程,是动态规划的核心。
初始状态:由已知能够确定的状态。
目标状态:表示解或能够转化为解的状态。
总体看来,由初始状态经过若干阶段通过若干决策推出目标状态的过程就是动态规划。下面我们就Number Triangles一题对这些概念对号入座:
首先确定状态,用F[I,J]表示从顶层走到第I行第J列的点能取得的最大和。显然每一层为一个阶段。而对于走到每一个非顶层点的情况来说,最多都只可能由它上方的点或左上方的点走来。则有状态转移方程:F[I,J] = Max(F[I-1,J], F[I-1,J-1])+ A[I,J];初始状态为F[1,1] = A[1,1];目标状态为F[N,K],其中K∈[1,N]。要求输出的解则是Max {F[N,K]} ,其中K ∈[1,N]。时空复杂度均为O(N2)。
这里给出程序主干部分:
F[1,1] = A[1,1]
For I = 2 to N Do
For J = 1 to I Do
If F[I-1,J] > F[I-1,J-1] Then
F[I,J] = F[I-1,J] + A[I,J]
Else
F[I,J] = F[I-1,J-1] + A[I,J]
接下来我们从理论上来讨论使用动态规划的条件。对于一种状态划分的方法来说,状态只与状态本身的性质有关,而与如何达到该状态等其他条件一概无关的性质叫做无后效性。由于存在无后效性,决策只能从决策本身的性质来确定,使得某一阶段的状态只与它所在阶段的前一阶段的状态有关。可以看出,存在无后效性是应用动态规划的前提条件。而考虑动态规划的正确性时,问题则需要满足最优子结构。所谓最优子结构,即当前一阶段的状态最优时,通过状态转移方程得到的状态也能达到最优。理论上看,无后效性和最优子结构是使用动态规划时的两个基本条件,而具体应用动态规划时更多凭借的是经验。
下面再引出一道经典题目做一下分析: