石子归并(动态规划)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

石子归并(动态规划)
动态规划石子合并问题
【石材加固】
在一个圆形操场的四周摆放着n堆石子。

现要将石子有次序地合并成一堆。

规定每次
只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。

尝试设计一个算法来计算将n堆石头合并成一堆的最小分数和最大分数。

[输入文件]
包含两行,第1行是正整数n(1<=n<=100),表示有n堆石子。

第2行有n个数,分别表示每堆石子的个数。

【输出文件】输出两行。

第1行中的数字是最低分数;第2行中的数字是最高分。

[输入示例]4
4459
[输出示例]4354
【分析】
起初,我以为贪心法可以解决这个问题,但事实上,由于必须有两个相邻的桩合并,
贪心法不能保证每次都能得到所有桩中石头数量最多的两个桩。

例如,以下示例:6
346542
如果使用贪心法计算最小分数,则应为以下合并步骤:第一次合并3465422,3合并分
数为5,第二次合并546545,4合并分数为9,第三次合并96545,4合并分数为9,第四次
合并9699,6合并分数为15,第五次合并15915,9合并分数为24,总分=5+9+9+15+24=62
但是如果采用如下合并方法,却可以得到比上面得分更少的方法:第一次合并3465423,4合并得分是7第二次合并765427,6合并得分是13第三次合并135424,2合并得分是6第四次合并13565,6合并得分是11第五次合并131113,11合并得分是24总得分=
7+13+6+11+24=61
因此,我们知道这个问题不能用贪婪的方法来解决。

在上面的例子中,相邻的两个石
子数量分别为13和11的桩第五次合并。

第一堆、第二堆和第三堆(石块数量分别为3、4和6)以及第四、第五和第六堆(石块数量分别为5、4和2)组合四次后形成两堆石块。

所以问题归结为如何使两个子序列的N-2组合分数之和达到最优。

为了实现这一目标,我
们将第一个序列分为两个:第一和第二堆形成子序列1,第三堆形成子序列2。

子序列1
中的两个桩首次合并,得分为7;第二次,将其与一堆子序列2相结合,得13分。

显然,这种合并方案对于第一个子序列是最好的。

同样,我们将第二个子序列分成两部分;第四
桩为子序列1,第五桩和第六桩为子序列2。

第三次,在子序列2中合并2个桩,得分为6;
将第四个孩子的分数与第十三个孩子的分数合并。

显然,这种合并方案对于第二个子序列
也是最好的。

由此,我们可以得出结论,有六堆石头通过这条路
的5次合并后,得分的总和最小。

动态规划思路:
第一阶段:每块石料的合并过程,先是2乘2,然后是3乘3,最后是n堆合并状态s:每个阶段不同合并方法的石料合并总分。

决策:把当前阶段的合并方法细分成前一阶段已计算出的方法,选择其中的最优方案
具体来说,我们应该定义一个数组s[I,J]来表示合并方法。

I代表从编号为I的石
头中合并,J代表从I开始从J个桩的数量中合并,s[I,J]是合并的最佳分数。

对于上面的例子来说,初始阶段就是s[1,1],s[2,1],s[3,1],s[4,1],s[5,1],s[6,1],因为一开始还没有合并,所以这些值应该全部为0。

第二阶段:第二阶段:将两者合并的过程如下:,(I,J)表示从I.s[1,2[1,1,1,1,1,1,1)1[1,(1,1,1,1)1,1,1)1,1,(1,1,2)s[2,1,1,1,1,1,1,J)以及(1,1,1,1,1,1,J)和(1,1,1,1,1,1,1,2)2)s[2,2)s[2,2,
2[2,2,2,2,2,2,2[2,2,2,2,1,2,1,2,2,1,1,1,2,1,1,1,1,1,
2[2[2,1,1,2,1,1,1,1,2,1,1,1,1,2,1,1,1,1][2,2,2,2,2,2,2,1,2,2,1,1][1,2)s[1,1]+s[5,1]+s[5,1]+s[5,1]+SM(6,2)
第三阶段:三三合并可以拆成两两合并,拆分方法有两种,前两个为一组或后两个为
一组s[1,3]=s[1,2]+s[3,1]+sum(1,3)或s[1,3]=s[1,1]+s[2,2]+sum(1,3),取其最优
s[2,3]=s[2,2]+s[4,1]+sum(2,3)或s[1,3]=s[2,1]+s[3,2]+sum(2,3),取其最优...
第四阶段:四和四相结合的分裂法使用三种方法。

同样,计算这三种方法的分数,然
后选择最好的一种。

在未来,第五阶段和第六阶段被类比,最终在第六阶段可以找到最佳
答案。

由此得到算法框架如下:
福吉← 2在{枚举阶段,从两个}forI的组合计算← 1 TONDO{计算当前阶段n个不同
状态的值}← 1toj-1开始{列举不同的分段方法}
ifi+k>nthent←(i+k)modnelset←i+k{最后一个连第一个的情况处理}s[i,j]←最优
{s[i,k]+s[t,j-k]+sum[1,3]}{sum[i,j]表示从i开始数j个数的和}end;
变量
n:integer;
a:longint的数组[1..100];
s:array[1..100,1..100]oflongint;t:array[0..100,0..100]oflongint;i,j,k,temp,max ,min:longint;begin
赋值(输入'shizi.in');复位(输入);readln(n);
fillchar(t,sizeof(t),0);{计算和数组}
fori:=1tondoread(a[i]);fori:=1tondoforj:=1tondo
fork:=itoi+j-1dobegin
如果k>nthentemp:=kmodnelstemp:=k;t[i,j]:=t[i,j]+a[temp];终止
{动态规划求最大得分}
fillchar(s,sizeof(s),0);forj:=2托福里:=1托福里:=1托福里:=1托福里:=1托福金。

相关文档
最新文档