动态规划奥赛完整版本.docVIP

  1. 1、本文档共23页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
动态规划奥赛完整版本.doc

第八章 动态规划 引言 在分治法一章中,为了解决一个大的问题,我们总是想方设法把它分成两个或多个更小的问题;然后分别解决每个小问题;再把各小问题的解答组合起来,即可得到原问题的解答;小问题通常与原问题本质相似,只是规模小些,一般都可以用递归的方法来解决,如hanoi塔问题和快速排序都是应用这种方法的典型例子。然而常常有些问题难以用分治法来求解,当把问题分解成若干个子问题,使之能够从这些子问题的解得到原问题的解时,子问题的数目太多,这样,如果把每个子问题再分解,必将得到更多的子问题,以至于最后解决问题需要耗费指数时间。往往在这类问题中子问题的数目其实只有多项式多个,于是在上述算法中,一定有些子问题被重复计算了许多次。如果我们能够保存已解决的子问题的答案,而在需要时简单查一下,这样我们就可以避免大量的重复计算,从而得到多项式时间的算法。 为了实现上述方法,我们用一个数组来记录所有已解决的子问题的答案。无论子问题以后是否被用到,只要它被计算过,就将其结果存入数组中,这种方法在程序设计中被称为动态规划,请看下面的实例。 例8_1: 数字三角形(IOI94) [问题描述] 如下所示为一个数字三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 请编一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。  ● 每一步可沿直线向下或右斜线向下走;  ● 1<三角形行数≤100;  ● 三角形中的数字为整数0,1,……,99; [输入] 输入文件第一行为一个自然数,表示数字三角形的行数n,接下来的n行表示一个数字三角形。 [输出] 输出文件仅有一行包含一个整数表示要求的最大总和。 [输入样例] 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 [输出样例] 30 [问题分析] 假设从顶至数字三角形的某一位置的所有路径中,所经过的数字的总和最大的那条路径我们称之为该位置的最大路径。由于问题规定每一步只能沿直线或右斜线向下走,若要走到某一位置,则其前一位置必为其左上方或正上方两个位置之一,由此可知,当前位置的最优路径必定与其左上方或正上方两个位置的最优路径有关,且来自于其中更优的一个。 我们可以用一个两维数组a记录数字三角形中的数,a[I,j]表示数字三角形中第I行第j列的数,再用一个两维数组maxsum记录每个位置的最优路径的数字总和。计算maxsum数组可以象计算杨辉三角一样用逐行递推的方法实现,具体细节请看程序清单。 [参考程序] Program p8_1(Input, Output); const maxline=100; var i,j,t,line:integer; a,max:array [1..maxline,1..maxline] of integer;function maxsum(i,j:integer):integer; begin if i=line then maxsum:=a[i,j] else if maxsum(i+1,j)maxsum(i+1,j+1) then maxsum:=maxsum(i+1,j)+a[i,j] else maxsum:=maxsum(i+1,j+1)+a[i,j] end;begin {main} write(Input number of line(=100):); readln(line); for i:=1 to line do begin for j:=1 to i do begin a[i,j]:=random(99)+1; write(a[i,j]:3) end; writeln end; writeln; writeln(Maxsum=,maxsum(1,1)); max[1,1]:=a[1,1]; for i:=2 to line do begin max[i,1]:=max[i-1,1]+a[i-1,1]; for j:=2 to i-1 do if a[i,j]+max[i-1,j]=a[i,j]+max[i-1,j-1] then max[i,j]:=a[i,j]+max[i-1,j] else max

您可能关注的文档

文档评论(0)

000 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档