- 1、本文档共3页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
数塔问题:
有形如图1.3-8所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走,一起走到底层,要求找出一条路径,使路径上的值最大。
?
??????????????????????????? 图1.3-8
这道题如果用枚举法,在数塔层数稍大的情况下(如40),则需要列举出的路径条数将是一个非常庞大的数目。
如果用贪心法又往往得不到最优解。
在用动态规划考虑数塔问题时可以自顶向下的分析,自底向上的计算。从顶点出发时到底向左走还是向右走应取决于是从左走能取到最大值还是从右走能取到最大值,只要左右两道路径上的最大值求出来了才能作出决策。同样的道理下一层的走向又要取决于再下一层上的最大值是否已经求出才能决策。这样一层一层推下去,直到倒数第二层时就非常明了。如数字2,只要选择它下面较大值的结点19前进就可以了。所以实际求解时,可从底层开始,层层递进,最后得到最大值。
实际求解时应掌握其编程的一般规律,通常需要哪几个关键数组来存储变化过程这一点非常重要。
数塔问题的样例程序如下:
var a:array[1..50,1..50,1..3] of longint;
{第一维记原状态,第二维参与计算,第三维记录决策,0向左,1向右。浪费啊,不如开三个一维,或三元组(指针处理麻烦,类似三角矩阵存储)}
i,j,n:integer;
begin
???? write( 'please input the number of rows:');
???? readln(n);
???? for i:=1 to n do
???????? for j:=1 to i do {行元素数等于行数}
???????? begin
????????????? read(a[i,j,1]);
????????????? a[i,j,2]:=a[i,j,1];
????????????? a[i,j,3]:=0
???????? end;
{计算=================================}
???? for i:=n-1 downto 1 do {行选择(始于倒数第二行),阶段}
???????? for j:=1 to i do {列选择,状态}
????????????? if a[i+1,j,2]>a[i+1,j+1,2] then {左强}
???????????????? begin a[i,j,2]:=a[i,j,2]+a[i+1,j,2];{累计结果(父+左)}a[i,j,3]:=0 {记录决策(选左)}end
????????????? else {右强}
????????????????? begin a[i,j,2]:=a[i,j,2]+a[i+1,j+1,2]; {累计结果(父+右)}a[i,j,3]:=1{记录决策(选右)} end;
{===输出==========}
writeln('max=',a[1,1,2]); {最大值}
??? j:=1;
???? for i:=1 to n-1 do
???? begin
????????? write(a[i,j,1],'->');
????????? j:=j+a[i,j,3]
???? end;
???? writeln(a[n,j,1])
end.
总结:此题是最为基础的动态规划题目,阶段、状态的划分一目了然。
而决策的记录,充分体现了动态规划即“记忆化搜索”的本质。
文档评论(0)