方格取数

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

方格取数

设有n*n的方格图(N≤8),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0。如下图所示(见样例):

向右

A 1 2 3 4 5 6 7 8

1

2

3

4

5

向 6

下7

8

某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B点。在走过的路上,它可以取走方格中的数(取走后的方格中将变为数字0)。此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和最大。

输入:输入的第一行为一个整数N(表示N*N的方格图),接下来的每行右三个整数,前两个表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。

输出:只需输出一个整数,表示2条路径上取得的最大的和

分析:我们对这道题并不陌生。如果求一条数和最大的路径,读者自然会想到动态程序设计方法。现在的问题是,要找出这样的两条路径,是否也可以采用动态程序设计方法呢?回答是可以的。

1、状态的设计

对于本题来说,状态的选定和存储对整个问题的处理起了决定性的作用。

我们从(1,1)出发,每走一步作为一个阶段,则可以分成2*n-1个阶段:第一个阶段,两条路径从(1,1)出发;

第二个阶段,两条路径可达(2,1)和(1,2);

第三个阶段,两条路径可达的位置集合为(3,1)、(2,2)和(1,3);

…………………………

第2*n-1个阶段,两条路径汇聚(n,n);

在第k(1≤k≤2*n-1)个阶段,两条路径的终端坐标(x1,y1)(x2,y2)位于对应的右下对角线上。如下图所示:

如果我们将两条路径走第i步的所有可能位置定义为当前阶段的状态的话,面对的问题就是如何存储状态了。方格取数问题的状态数目十分庞大,每一个位置是两维的,且又是求

两条最佳路径,这就要求在存储上必须做一定的优化后才有可能实现算法的程序化。主要的优化就是:舍弃一切不必要的存储量。为此,我们取位置中的x坐标(x1,x2)作状态,其中

(1≤x1≤k)and(x1∈{1‥n})and(1≤x2≤k)and(x2∈{1‥n})

直接由X坐标计算对应的Y坐标:

(y1=k+1-x1)and(y1∈{1‥n})and(y2=k+1-x2)and(y2∈{1‥n})

2、状态转移方程

设两条路径在k阶段的状态为(x1,x2)。由(y1=k+1-x1)∧(y1∈{1..n})得出第一条路径的坐标为(x1,y1);由(y2=k+1-x2)∧(y2∈{1..n})得出第二条路径的坐标为(x2,y2)。假设在k-1阶段,两条路径的状态为(x1’,x2’)且(x1’,x2’)位于(x1,x2)状态的左邻或下邻位置。因此我们设两条路径的延伸方向为d1和d2:d i=0,表明第i条路径由(x i’,y i’)向右延伸至(x i,y i);d i=1,表明第i条路径由(x i’,y i’)向下延伸至(x i,y i)(1≤i≤2)。显然(x1’= x2’)∧(d1= d2),表明两条路径重合,同时取走了(x1’,y1’)和(x1,y1)中的数,这种取法当然不可能得到最大数和的。

分析两种可能:

⑴若x1=x2,则两条路径会合于x1状态,可取走(x1,y1)中的数(如下图);

x1’(x2’)→x1=x2

x2’(x1’)

⑵若x1≠x2,则在k阶段,第一条路径由x1’状态延伸至x1状态,第二条路径由x2’状态延伸至x2状态,两条路径可分别取走(x1,y1)和(x2,y2)中的数(如下图);

f[k,x1,x2]—在第k阶段,两条路径分别行至x1状态和x2状态的最大数和。显然k=1时,f[1,1,1]=0;

k≥2时,f[k,x1,x2]=max{f[k-1, x1’,x2’]+(x1,y1)的数字▏x1=x2

f[k-1, x1’,x2’]+(x1,y1)的数字+(x2,y2)的数字▏x1≠x2}

1≤k≤2*n-1,x1’∈可达x1的状态集合,x2’∈可达x2的状态集合,(x1’≠x2’)∨(d1≠d2);

上述状态转移方程符合最优子结构和重叠子问题的特性,因此适用于动态程序设计方法求解。由于第k个阶段的状态转移方程仅与第k-1个阶段的状态发生联系,因此不妨设

f0—第k-1个阶段的状态转移方程;

f1—第k个阶段的状态转移方程;

初始时,f0[1,1]=0。经过2*n-1个阶段后得出的f0[n,n]即为问题的解。

3、多进程决策的动态程序设计

由于方格取数问题是对两条路径进行最优化决策的,因此称这类动态程序设计为分阶段、多进程的最优化决策过程。设

阶段i:准备走第i步(1≤i≤2*n-1);

状态(x1’,x2’):第i-1步的状态号(1≤x1’,x2’≤i-1。x1’,x2’∈{1..n})

决策(d1,d2):第一条路径由x1’状态出发沿d1方向延伸、第二条路径由x2’状态出

发沿d2方向延伸,可使得两条路径的数和最大(0≤d1,d2≤1。方向

0表示右移,方向1表示下移);

具体计算过程如下:

fillchar(f0,sizeof(f0),0); { 行走前的状态转移方程初始化}

f0[1,1]←0;

for i←2 to n+n-1 do {阶段:准备走第i步}

begin

fillchar(f1,sizeof(f1),0); { 走第i步的状态转移方程初始化}

for x1’←1 to i-1 do {枚举两条路径在第i-1步时的状态x1’和x2’}

for x2’←1 to i-1 do

begin

计算y1’和y2’;

if (x1’,y1’)和(x2’,y2’)在界内 then

for d1←0 to 1 do {决策:计算两条路径的最佳延伸方向}

for d2←0 to 1 do

begin

第1条路径沿d1方向延伸至(x1,y1);

第2条路径沿d2方向延伸至(x2,y2);

if ((x1,y1)和(x2,y2)在界内)∧((d1≠d2)∨(x1≠x2)) {计算第i步的状态转移方程}

then f1[x1,x2]←max{f0[x1’,x2’]+map[x1,y1]∣x1=x2,f0[x1’,x2’]+map[x1,y1]+map[x2,y2]∣x1≠x2}

end;{for}

end;{for}

f0←f1; {记下第i步的状态转移方程}

end;{for}

输出两条路径取得的最大数和f0[n,n];

相关文档
最新文档