石子合并问题宝贝_第1页
石子合并问题宝贝_第2页
石子合并问题宝贝_第3页
石子合并问题宝贝_第4页
石子合并问题宝贝_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、石子合并(动态规划)宝贝报告一试题在一个园形操场的四周摆放N堆石子(N100),现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。编一程序,由文件读入堆数N及每堆的石子数(),选择一种合并石子的方案,使得做N1次合并,得分的总和最小;选择一种合并石子的方案,使得做N1次合并,得分的总和最大。例如,所示的堆石子,每堆石子数(从最上面的一堆数起,顺时针数)依次为。则次合并得分总和最小的方案:得分最大的方案为:输入数据:文件名由键盘输入,该文件内容为:第一行为石子堆数N;第二行为每堆的石子数,每两个数之间用一个空格符分隔。输出数据:输出文

2、件名为output.txt从第1至第N行为得分最小的合并方案。第N1行是空行。从第N2行到第2N1行是得 分最大合并方案。每种合并方案用N行表示,其中第i行(1iN)表示第i 次合并前各堆的石子数(依顺时针次序输出,哪一堆先输出均可)。 要求将待合并的两堆石子数以相应的负数表示,以便标识。输入输出范例:输入文件内容: 输出文件内容: 二算法分析竞赛中多数选手都不约而同地采用了尽可能逼近目标的贪心法来逐次合并:从最上面的一堆开始,沿顺时针方向排成一个序列。 第一次选得分最小(最大)的相邻两堆合并,形成新的一堆;接下来,在N1堆中选得分最小(最大)的相邻两堆合并,依次类推, 直至所有石子经N1次合

3、并后形成一堆。例如有堆石子,每堆石子数(从最上面一堆数起,顺时针数)依次为 要求选择一种合并石子的方案,使得做次合并,得分的总和最小。按照贪心法,合并的过程如下:每次合并得分第一次合并 ->第二次合并 ->第三次合并 ->第四次合并 ->第五次合并 ->24总得分但是当我们仔细琢磨后,可得出另一个合并石子的方案:每次合并得分第一次合并 ->第二次合并 ->第三次合并 ->第四次合并 ->第五次合并 ->24总得分显然,后者比贪心法得出的合并方案更优。 题目中的示例故意造成一个贪心法解题的假像,诱使读者进入“陷阱”。为了帮助读者从这个“

4、陷阱”里走出来, 我们先来明确一个问题:最佳合并过程符合最佳原理使用贪心法至所以可能出错,是因为每一次选择得分最小(最大)的相邻两堆合并,不一定保证余下的合并过程能导致最优解。聪明的读者马上会想到一种理想的假设:如果N1次合并的全局最优解包含了每一次合并的子问题的最优解,那么经这样的N1次合并后的得分总和必然是最优的。例如上例中第五次合并石子数分别为和的相邻两堆。这两堆石头分别由最初的第,堆(石头数分别为,)和第,堆(石头数分别为,)经次合并后形成的。于是问题又归结为如何使得这两个子序列的N2 次合并的得分总和最优。为了实现这一目标,我们将第个序列又一分为二:第、堆构成子序列,第堆为子序列。第

5、一次合并子序列中的两堆,得分;第二次再将之与子序列的一堆合并,得分。显然对于第个子序列来说,这样的合并方案是最优的。同样,我们将第个子序列也一分为二;第堆为子序列,第,堆构成子序列。第三次合并子序列中的堆,得分;第四次再将之与子序列中的一堆合并,得分。显然对于第二个子序列来说,这样的合并方案也是最优的。由此得出一个结论堆石子经过这样的次合并后,得分的总和最小。我们把每一次合并划分为阶段,当前阶段中计算出的得分和作为状态,如何在前一次合并的基础上定义一个能使目前得分总和最大的合并方案作为一次决策。很显然,某阶段的状态给定后,则以后各阶段的决策不受这阶段以前各段状态的影响。这种无后效性的性质符最佳

6、原理,因此可以用动态规划的算法求解。动态规划的方向和初值的设定采用动态规划求解的关键是确定所有石子堆子序列的最佳合并方案。 这些石子堆子序列包括:第堆、第堆、第堆、第堆、第N堆、第堆;第堆、第堆、第堆、第堆、第堆、第堆、第N堆、第堆、第堆;第堆、第N堆第2堆、第N堆、第堆第N堆、第堆、第N堆为了便于运算,我们用i,j表示一个从第i堆数起,顺时针数j堆时的子序列第i堆、第i堆、第(ij1)mod n堆它的最佳合并方案包括两个信息:在该子序列的各堆石子合并成一堆的过程中,各次合并得分的总和;形成最佳得分和的子序列和子序列。由于两个子序列是相邻的, 因此只需记住子序列的堆数;设fi,j将子序列i,j

7、中的j堆石子合并成一堆的最佳得分和;ci,j将i,j一分为二,其中子序列的堆数;(iN,jN)显然,对每一堆石子来说,它的fi,ci, (iN)对于子序列i,j来说,若求最小得分总和,fi,j的初始值为; 若求最大得分总和,fi,j的初始值为。(iN,jN)。动态规划的方向是顺推(即从上而下)。先考虑含二堆石子的N个子序列(各子序列分别从第堆、第堆、第N堆数起,顺时针数堆)的合并方案 f,f,fN,c,c,cN,然后考虑含三堆石子的个子序列(各子序列分别从第堆、第堆、第堆数起,顺时针数堆)的合并方案f,f,fN,c,c,cN,依次类推,直至考虑了含N堆石子的N个子序列(各子序列分别从第堆、第堆

8、、 、第N堆数起,顺时针数N堆)的合并方案f,N,f,N,fN,Nc,N,c,N,cN,N最后,在子序列,N,N,N,N中,选择得分总和(f值)最小(或最大)的一个子序列i,N(iN),由此出发倒推合并过程。动态规划方程和倒推合并过程对子序列i,j最后一次合并,其得分为第i堆数起,顺时针数j堆的石子总数t。被合并的两堆石子是由子序列i,k和(ik)modn,jk(kj)经有限次合并形成的。为了求出最佳合并方案中的k值,我们定义一个动态规划方程:当求最大得分总和时fi,jmaxfi,kfx,j-ktkjci,jk fi,jfi,kfx,j-kt(,)当求最小得分总和时fi,jminfi,kfx,

9、jktkjci,jk fi,jfi,kfx,j-kt(,)其中x(ik)modn,即第i堆数起,顺时针数k堆的堆序号。例如对上面例子中的( )堆石子,按动态规划方程顺推最小得分和。 依次得出含二堆石子的个子序列的合并方案f, f, f ,c, c, c,f, f, f,c, c, c,含三堆石子的( )个子序列的合并方案f, f, f,c, c, c,f, f, f,c, c, c,含四堆石子的( )个子序列的合并方案f, f, f,c, c, c,f, f, f,c, c, c,含五堆石子的( )个子序列的合并方案f, f, f,c, c, c,f, f, f,c, c, c,含六堆石子的(

10、 )个子序列的合并方案f, f, f,c, c, c,f, f, f,c, c, c,f,是f,f,中的最小值,表明最小得分和是由序列,经次合并得出的。我们从这个序列出发,按下述方法倒推合并过程:由c,可知,第次合并的两堆石子分别由子序列,和子序列,3经次合并后得出。其中c,可知由子序列,合并成的一堆石子是由子序列,和第三堆合并而来的。而c,以表明了子序列,的合并方案是第堆合并第堆。由此倒推回去,得出第,第次合并的方案,每次合并得分第一次合并 ->第二次合并 ->子序列,经次合并后合并成堆, 次合并的得分和。,可知由子序列,合并成的一堆石子是由第堆和子序列,合并而来的。而c,又表明

11、了子序列,的合并方案是第堆合并第堆。由此倒推回去,得出第、第次合并的方案 每次合并得分:第三次合并 ->第四次合并 ->子序列,经次合并后合并成堆,次合并的得分和。第五次合并是将最后两堆合并成堆,该次合并的得分为。显然,上述次合并的得分总和为最小上述倒推过程,可由一个print(子序列)的递归算法描述procedure print (i,)beginif then 继续倒推合并过程beginprint(i,ci,j;倒推子序列的合并过程print(ici,jmod n,jci,j)倒推子序列的合并过程for K: to N do输出当前被合并的两堆石子if (第K堆石子未从圈内去除

12、)then beginif(Ki)or(KX)then置第K堆石子待合并标志else第K堆石子未被合并;end;then第i堆石子数第i堆石子数第X堆石子数;将第X堆石子从圈内去除;end;thenend;print例如,调用print(,)后的结果如下:print(,)print(,) print(,) print(,) print(3,1) print(4,1) print(,) print(1,1) print(2,1) print(5,1)print(6,1)(图6.2-5)其中回溯至 显示 显示 显示 显示 显示 注:调用print过程后,应显示堆石子的总数作为第次合并的得分。Pro

13、gram Stones;TypeNode = Record当前序列的合并方案c : Longint;得分和d : Byte子序列1的堆数End;SumType = Array 1.100,1.100 of Longint;sumtypei,j-子序列i,j的石子总数VarList : Array 1.100,1.100 of Node;listi,j-子序列i,j的合并方案Date, Dt : Array 1.100 of Integer;Datei-第i堆石子数,Dt-暂存DateSum : SumType;sumi,j-指向子序列i,j的石子总数的指针 F : Text;文件变量Fn :

14、String;文件名串N, i, j : Integer;N-石子堆数,i,j-循环变量Procedure Print(i, j : Byte);递归打印子序列i,j的合并过程 Vark, x : Shortint;k-循环变量;x-子序列2中首堆石子的序号BeginIf j <> 1 Then Begin继续倒推合并过程Print(i, Listi,j.d);倒推子序列1的合并过程x := (i + Listi, j.d - 1) Mod N + 1;求子序列2中首堆石子的序号 Print(x, j - Listi, j.d);倒推子序列2的合并过程For k := 1 to N

15、 Do输出当前合并第i堆,第x堆石子的方案If Datek > 0 Then BeginIf (i= k)or(x=k)Then Write(F, - Datek, ' ')Else Write(F, Datek, ' ')End; Then Writeln(F);输出换行符Datei := Datei + Datex;原第i堆和第x堆合并成第堆 Datex := - Datex将原第x堆从圈内去除End Then End; Print Procedure Main(s : Shortint);Vari, j, k : Integer;t, x : Lon

16、gint;BeginFor i := 1 to N Do Begin仅含一堆石子的序列不存在合并Listi, 1.c := 0;Listi, 1.d := 0End; ForFor j := 2 to N Do顺推含2堆,含3堆含N堆石子的各子序列的合并方案 For i := 1 to N Do Begin当前考虑从第i堆数起,顺时针数j堆的子序列If s = 1 Then Listi, j.c := Maxlongint合并i,j子序列的得分和初始化 Else Listi, j.c := 0;t := Sumi, j;最后一次合并的得分为i,j子序列的石子总数For k := 1 to j

17、- 1 Do Begin子序列1的石子堆数依次考虑1堆j-1堆 x := (i + k - 1) Mod N + 1;求子序列2首堆序号If (s=1) And (Listi,k.c + Listx,j-k.c+t < Listi, j.c) Or (s=2) And (Listi,k.c + Listx,j-k.c+t > Listi, j.c) 若该合并方案为目前最佳,则记下Then BeginListi, j.c := Listi, k.c + Listx, j - k.c + t;Listi, j.d := kEnd Then End For End; For 在子序列1,

18、N,2,N,N, N中选择得分总和最小(或最大)的一个子序列 k := 1; x := List1, N.c;For i := 2 to N DoIf (s = 1) And (Listi, N.c < x) Or (s = 2) And(Listi, N.c > x) Then Begink := i; x := Listi, N.cEnd; Then Print(k, N);由此出发,倒推合并过程Writeln(F, Sum1, N);输出最后一次将石子合并成一堆的石子总数Writeln(F);Writeln(listk, N.c)End; Main BeginWrite('File name = ');输入文件名串Readln(Fn);Assign(F, Fn);该文件名串与文件变量连接Reset(F);文件读准备Readln(F, N);读入石子堆数For i := 1 to N Do Read(F, Datei);读入每堆石子数 New(Sum);求每一个子序列的石子数sumFor i :=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论