ImageVerifierCode 换一换
格式:DOCX , 页数:56 ,大小:229.91KB ,
资源ID:7645577      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7645577.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(动态规划 周谷越.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

动态规划 周谷越.docx

1、动态规划 周谷越信息学竞赛中的动态规划专题 哈尔滨工业大学 周谷越【关键字】动态规划 动机 状态 典型题目 辅助方法 优化方法【摘要】 本文针对信息学竞赛(面向中学生的Noi以及面向大学生的ACM/ICPC)中的动态规划算法,从动机入手,讨论了动态规划的基本思想和常见应用方法。通过一些常见的经典题目来归纳动态规划的一般作法并从理论上加以分析和说明。并介绍了一些解决动态规划问题时的一些辅助技巧和优化方法。纵观全文可知,动态规划的关键在于把握本质思想的基础上灵活运用。【目录】1.动态规划的动机和基本思想1.1.解决重复子问题1.2.解决复杂贪心问题2.动态规划状态的划分方法2.1.一维状态划分 2

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 解决重复子问题 对于很多问题,我们利用分治的思想,可以把大问题分解成若干小问题,然后再把各个小问题的答案组合起来,得到大问题的解答。这类问题的共同点是小问题和大问题的本质相同。很多分治法可以解决的问题(如

3、quick_sort,hanoi_tower等)都是把大问题化成2个以内的不相重复的小问题,解决的问题数量即为(log2n / k)。而考虑下面这个问题:USACO 1.4.3 Number Triangles【题目描述】考虑在下面被显示的数字金字塔。写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。每一步可以走到左下方的点也可以到达右下方的点。73 88 1 02 7 4 44 5 2 6 1在上面的样例中,从7到3到8到7到5的路径产生了最大和:30。【输入格式】第一个行包含 R(1= R FI-1,J-1 Then FI,J = FI-1,J + AI,J Else

4、FI,J = FI-1,J-1 + AI,J接下来我们从理论上来讨论使用动态规划的条件。对于一种状态划分的方法来说,状态只与状态本身的性质有关,而与如何达到该状态等其他条件一概无关的性质叫做无后效性。由于存在无后效性,决策只能从决策本身的性质来确定,使得某一阶段的状态只与它所在阶段的前一阶段的状态有关。可以看出,存在无后效性是应用动态规划的前提条件。而考虑动态规划的正确性时,问题则需要满足最优子结构。所谓最优子结构,即当前一阶段的状态最优时,通过状态转移方程得到的状态也能达到最优。理论上看,无后效性和最优子结构是使用动态规划时的两个基本条件,而具体应用动态规划时更多凭借的是经验。下面再引出一道

5、经典题目做一下分析:ACM/ICPC Shanghai2001 Skiing【题目描述】滑雪是一项很受欢迎的体育运动,为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡。我们想知道载一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9我们可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-.-3-2-1更长。事实上,这是最长的一条。

6、【输入格式】 输入的第一行表示区域的行数R和列数C(1 = R,C = 500)。下面是R行,每行有C个整数,代表高度h,0=h 0 Then Return ArrI,J Int P, Ans = 0 For P = 1 to 4 Do If (I+DXP,J+DYP) In Map) And (HI+DXP,J+DYP HI,J) Then If (Ans FI+DXP,J+DYP) Ans = FI+DXP,J+DYP ArrI,J = Ans + 1 Return ArrI,J 同样是动态规划,是什么使得两道题目代码的主干部分相差巨大呢?这里讨论一下动态规划的两种实现形式递推和记忆化搜索

7、。首先,可以说所有用递推实现的动态规划均可以利用记忆化搜索实现。而某些题目之所以可以用递推求解,是因为这类题目同一阶段的状态表示上有很大的相关性,比如数字矩阵中某一行或列,这使得我们可以计算一个阶段的所有状态后再计算下一状态。而某些题目中利用动态规划划分的同一阶段的状态表示上没有多大相关性,比如Skiing里面的状态,从某点做起点每滑动一步为一个阶段,我们无法用一个准确的可以直接利用的集合将一个阶段中的状态表示出来,只能从已知状态去找和它相关联的状态。对于Skiing我们已知的是目标状态(即四面都不比该点高的点),通过边界条件(即四面都比该点高的最优值为1),便可以进行记忆化搜索。利用递推实现

8、动态规划时,单位操作时间小,可以方便地使用一些优化;而利用记忆化搜索实现动态规划时,单位操作时间大,但可以避免计算一些不必要的状态。总地来说,相比于用状态空间搜索的方法解决这类存在重复子问题的题目,使用动态规划增大了空间的开销,但提高了时间效率。1.2 解决复杂贪心问题 接下来,进入下一话题。我们考虑一下我们熟知的贪心算法和动态规划的关系,我看过很多写贪心算法和动态规划之间区别的材料,在这里我们不谈这个,而是要讨论动态规划与贪心算法之间的联系。 如果我们把每一步贪心作为一个阶段,那么可以认为每个阶段只有一个状态,再把贪心策略看作状态转移方程,那么这样是否也是一种“动态规划”呢?实际上,它们二者

9、之间的差别就在数据的维护上,有很多贪心问题在采取一次贪心策略之后要对数据进行全盘的维护,而我们讲的动态规划一般没有这个步骤。 而这个维护的目的是什么呢?是为了保证正确性,和动态规划中的最优子结构的目的一样,那么就说明目前的状态划分不具有最优子结构,那么我们是否能够通过改变状态的划分方法来代替这个维护并使新划分的状态具有最优子结构呢?这里直接给出结论:对于某些分步讨论的贪心决策问题,我们可以通过扩展状态使之能够用动态规划解决。扩展出的状态的作用就是为了保证正确性,也就是保证最优子结构。举一个简单的例子:给出N个数,要从其中取M个求和,并使和尽量大。这明显是一个贪心可解的问题,把数字从大到小排序后

10、取前M个求和即可。那么我们同样也可以扩展出一部分状态。我们设FI,J表示前I个数字中取了J个数字得到的最大和,则有:FI,J = Max (FI1,J,FI-1J-1 + AJ)。那些贪心算法并不用考虑的“多余”状态就是扩展出的状态,举个实例来说明:N = 5 , M = 3时,A = 1, 2, 3, 4, 5。那么显然1和2都不会被取到,但数组F中的F1,1, F2,1 和F2,2都是由1和2组成的状态,从贪心的角度看,它们就是多余的,就是为了使用动态规划扩展出来的状态。当然,就这道题目来看,贪心算法无论是从思维角度、编程角度还是时空复杂度角度都明显优于动态规划。HCPC Spring 2

11、007 Hurdles Race【题目描述】 自从刘翔在雅典夺得110米栏冠军之后,国人对跨栏比赛的关注程度大大提高。阿月和同学们经常在一起讨论刘翔需要用多少步来完成比赛,大家对该问题的意见不太一致,经常为此争论不休。我们下面定义这样一种跨栏比赛:tl表示起点到终点的距离(可能不是110);sl表示刘翔一步可以跨越的最大距离(我们规定刘翔每次跨越的距离必需是整数);fl表示第一个栏到起点的距离(fltl); n表示栏的数目;d表示每两个栏之间的距离(我们保证最后一个栏到起点的距离小于tl);每次跨栏的时候,刘翔都要保证栏的位置恰好在他跨越距离的正中间。求在这些条件下刘翔完成比赛所需要的最小步数

12、。【输入格式】输入包括五个正整数,分别表示tl,sl,fl,n,d(tl不超过10000,sl不超过10)。【输出格式】输出包括一个整数,即刘翔完成比赛所需要的最小步数。【样例输入】110 3 20 10 5【样例输出】41【样例说明】起点到跨过第一个栏至少需要8步,之后每跨一个栏至少需要2步,从跨过最后一个栏到终点至少需要15步。由于只有跨栏的那步有限制条件,其它步没有,故有了贪心思想跨栏那步要尽可能的大。通过分情况讨论后得到解:跨第一个栏之前的步数 + 栏的个数 + 跑2个栏之间路程需要的步数 (栏的个数 - 1) + 最后一个栏需要的步数。需要考虑的特殊情况只有跨第一个栏的步长未必可以达

13、到跨其它栏的步长。当然,如果比赛的时候可以快速地想到这个方法是最好不过的。实际上,使用动态规划更容易建立方程。设FI表示到达i位置所需要的最小步数,则有Fi=minFI-K+1,K=1.sl,其中I-K到I之间没栏;而有栏时,FI=minFI-2*sp+1,FI,sp为栏到i点距离。AsyzOI2007 营养膳食【题目描述】阿月正在女朋友宁宁的监督下完成自己的增肥计划。为了增肥,阿月希望吃到更多的脂肪。然而也不能只吃高脂肪食品,那样的话就会导致缺少其他营养。阿月通过研究发现:真正的营养膳食规定某类食品不宜一次性吃超过若干份。比如就一顿饭来说,肉类不宜吃超过1份,鱼类不宜吃超过1份,蛋类不宜吃超

14、过1份,蔬菜类不宜吃超过2份。阿月想要在营养膳食的情况下吃到更多的脂肪,当然阿月的食量也是有限的。【输入格式】输入第一行包含三个正整数n(n200),m(m100)和k(k100)。表示阿月每顿饭最多可以吃m份食品,同时有n种食品供阿月选择,而这n种食品分为k类。第二行包含k个不超过10的正整数,表示可以吃1到k类食品的最大份数。接下来n行每行包括2个正整数,分别表示该食品的脂肪指数ai和所属的类别bi,其中ai100,bik。【输出格式】输出一个数字即阿月可以吃到的最大脂肪指数和。【样例输入】6 6 33 3 215 115 210 215 210 25 3【样例输出】60用贪心算法解决,就

15、是把食品按脂肪指数排序后,在满足约束条件的情况下从大的开始吃,每吃一个更新一下约束条件。而用动态规划思想解决的话,可以设FI,J表示前I类食品一共吃J份能够获得的最大脂肪数和。则有FI,J = Max FI-1,K + GI,J-K,其中GI,J表示第I类食品种脂肪数最大的J份的和(也是要排序的)。Noip1999 旅行家的预算【题目描述】一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)。每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格 P

16、i(i=l,2,.,N)。如果无法到达目的地,则输出“No solution”。否则输出最小费用,计算结果四舍五入至小数点后两位。【样例输入】275.6 11.9 27.4 2.8 21 102.0 2.92 220.0 2.2【样例输出】26.95我们假设现在在第I站,那么可知在该站加满油可以到达的最远距离。如果在这个范围内存在一个加油站J,它的价格比I便宜,那么只要把油加到刚好能到达第一个出现的J即可;否则就在I加满油,选择范围内最便宜的加油站J,开到J再做决策。如果觉得这个方法不是很好想的话,就用动态规划实现之。设FI,J表示到达第I个加油站油量为J需要的最小费用,则有FI,J = Mi

17、n FI-1, J-K-G(I-1,I) + K*AI,其中G(I-1,I)表示第I个加油站和前一个加油站间的距离,AI表示第I个加油站的油价。对于以上三道题目,实现贪心更容易,而想到动态规划更容易(前提是对动态规划足够熟练),可以根据实际情况选择合适的算法。下面再给出两个相对复杂的题目。AsyzOI2005 雇工【题目描述】一中搬到新校舍,值得庆祝。但我们亲爱的电教老师FJ(Feng Jun not Farmer John)却遇到了个麻烦事。科技馆还没完全建好,需要雇人来完成一些后续工作。现在的行情是这样的:你雇佣一个人得给A元,解雇一个人得给人家B元(精神损失费),当然还有工资,每月K元。

18、有一系列工作,需要N月来完成。当然,不是每个月都需要相同的人数。可是当你雇佣一个雇工,不管他干不干活,都得给他工资(吃大锅饭)。说明一下:到期的时候是不用付精神损失费的。 请你帮帮FJ老师,他心系学校,绝对要为一中省钱。【输入格式】输入包含三行。第一行为N(不大于12的正整数)。第二行有三个数,A,K,B (J均不大于100)。第三行为每个月需要的最少人数(均小于1000)。【输出格式】输出包括一个数字即最小费用。【样例输入】34 5 610 9 11【样例输出】199考虑每一个月,比较当前的工人数M1和下一个月所需要的工人数M2,若M1M2,则必须雇佣缺少的工人,当然也不会多雇。问题的关键就

19、在于可以解雇的时候解雇多少工人,可以认为对于一组给定的A,K和B就可以得到一个吃大锅饭的最长时间(超过该时间可以解雇了后再雇佣),这样我们找到这个时间内的最大工人需求量M3,若M1M3,那么不用解雇任何工人,否则就要解雇M1 - M3个工人。需要注意的是,判断最长时间时需要考虑到期的时候不付精神损失费的特殊情况。而采用动态规划则要简单得多。设FI,J表示完成了前I个月的工作任务且第I个月有J个工人所需的最小费用,则有FI,J = Min FI-1,H + G(H,J) + K*J,其中G(H,J)表示由H个工人变化到J个工人所要支付的费用(或雇佣或解雇)。使用动态规划来解决这道题目,无论从思路

20、还是实现来说都要比贪心算法简单。在有规定时间限制的竞赛中,做题的速度也很重要。这催生了我们使用动态规划的第二个动机解决复杂的分步讨论的贪心决策问题。但仅限于数据范围不大的情况,因为较比贪心算法,动态规划的时间复杂度要大一些。总地来说,这类动态规划牺牲了程序的时空效率,但思维和编程比较简单,可以节约宝贵的竞赛时间。2.动态规划的状态划分方法 在这里我们把动态规划状态的划分方法分为3种:一维状态划分、二维状态划分和树型状态划分。树型动态规划是由于树这种数据结构的特殊性衍生出来的(放在最后说),这里先讨论一下一维状态划分和二维状态划分的动态规划。前面提到的动态规划基本都属于一维状态划分,以Numbe

21、r Triangles的方程为例(FI,J表示从顶层走到第I行第J列的点能取得的最大和)。定义I为阶段变量,J为状态变量(我为了自圆其说,方便讲解,自己定义的),阶段变量可以确定状态所在阶段,而状态变量则反映状态本身的性质。允许只有阶段变量没有状态变量,例如Hurdles Race里的FI。而前面提到的二维状态划分只有Skiing一题(FI,J表示滑到第I行第J列的点时存在的最长滑坡长度),因为这里I和J两个变量才能确定状态所在的阶段。2.1.1 典型的线性动态规划我们通常说的线性动态规划就是一维状态划分的没有状态变量的动态规划。下面了列举几个典型的线性动态规划题图:UVA 10684 The

22、 Jackpot【题目描述】 某人想迅速变得富有,但是他还不想工作。于是他开始赌博,存在一个奖金序列(有正有负),他想从中赢得最多的钱,我们规定他中途只可以退出一次(退出后不可以再回来)。【输入格式】输入第一行包含一个正整数N(N10000),接下里包含N个整数,它们的绝对值都不超过1000。【输出格式】 输出该人能赢得的最大钱数。【样例输入】512 -4 -10 4 9【样例输出】13 我们称该类问题为最大连续数字和。设FI表示到I为止(必须含AI)的最大连续整数和,如果FI-1为负数,那么显然FI = AI,否则有FI = FI-1 + AI。这样就构造出一个线性动态规划算法了,以下是它的

23、一个经典应用:NECPC2007 Sum Of SubRectangular Parallelepiped【题目描述】现有一个棱长为n的立方体,可以分成n3个1*1*1的单位立方体。每个单位立方体都有一个整数值。现在要求在这个立方体找到一个包含完整单位立方体的长方体,使得该长方体内所有单位立方体的数和最大。【输入格式】第一行包含一个整数n。接下来n个n2的数字矩阵,每个数字矩阵代表一层,每个数字代表一个单位立方体的整数值。【输出格式】输出仅包括最大的长方体的数和。【样例输入】21 22 1-1 2-2 -1【样例输出】6 最基础的方法是“直译”枚举过程,时间复杂度O(n9)。而记录先前考察的结

24、果。如图所示,在统计长方体2时,只要将长方体1的统计结果加上长方体3就可以了,而不必按上述算法那样重新进行计算。经过这样的优化,利用了前面的计算结果,时间复杂度降为O(n8)。 而对于每个平面的矩形有一种经典的压缩方法,设recx,y,z表示z轴坐标为z的水平面中矩形(1,1,x,y)的数和。则z轴坐标为z的水平面中左上角为(x1,y1)、右下角为(x2,y2)的矩阵的数和为recx2,y2,z + recx1,y1,z - recx2,y1,z - recx1,y2,z。 有了上面的关系式,我们下面要做的只是枚举z,x1,x2,y1,y2来查找最优解。对于每组固定的x1,x2,y1,y2,r

25、ecz, x1,x2,y1,y2就等于z个数字,那么只要求它们的最大连续和就可以。总的时间复杂度为O(n5)。Noip2004 合唱队型【题目描述】N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,K,他们的身高分别为T1,T2,TK,则他们的身高满足T1.Ti+1TK(1iK)。你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。【输入格式】第一行是一个整数N(2N106),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130Ti

26、230)是第i位同学的身高(厘米)。【输出格式】只包含一个整数,就是最少需要几位同学出列。【样例输入】8186 186 150 200 160 130 197 220【样例输出】4 首先只考虑左半部分的合唱队型,这种题目类型叫做最长上升子序列问题(LIS),最常规的算法是设FI表示前I个数字中(必须包含AI)的最长上升子序列的长度,状态转移方程为FI = Max FJ + 1,其中J0,I-1 且AJ AI。I和J都需要枚举,所以时间复杂度为O(n2)。 实际上LIS有一种贪心算法,我们用数组GI记录当前长度为I的上升子序列的最后一个元素的最小值,那么GI将会是一个单调的序列。对于每一个AJ,只要在G序列中找到一个最大的I,使得GI AJ,那么就可以在它的后面插入AJ就形成了当前的最长上升子序列,接下来需要更新G(当然只是其中的一个元素

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1