1、骑士游历问题设有一个 n*m 的棋盘(2n50,2m50),如下图。在棋盘上任一点有一个中国象棋马,马走的规则为:1.马走日字 2.马只能向右走。即下图所示:当 n,m 给出之后,同时给出马起始的位置和终点的位置,试找出从起点到终点的所有路径的数目。例如:(n=10,m=10),(1,5)(起点),(3,5)(终点)。应输出 2(即由(1,5)到(3,5)共有 2 条路径,如下图):输入:n,m,x1,y1,x2,y2(分别表示 n,m,起点坐标,终点坐标)输出:路径数目(若不存在从起点到终点的路径,输出 0)分析:使用回溯法是可以计算路径数目,但问题是搜索效率太低,根本不可能在较短的时间内出
2、解。因为题目并不要求每一条路径的具体走法。在这种情况下,是否非得通过枚举所有路径方案后才能得出路径数目,有没有一条简便和快效的“捷径”呢。从(x 1,y 1)出发,按照由左而右的顺序定义阶段的方向。位于(x,y)左方且可达(x,y)的跳马位置集合都是(x,y)的子问题,起点至(x,y)的路径数实际上等于起点至这些位置集的路径数之和(如下图) 。如此一来,状态转移关系便凸显出来。设状态转移方程 map,其中 mapi,j为起点(x1,y1)至(i,j)的路径数目。由于棋盘规模的上限为 50*50,可能导致路径数目大得惊人,因此不妨设 map 数组的元素类型为 extended。初始时,除 map
3、x1,y1=1 外其余为。显然 ),(, ),),( 在 界 内的 坐 标 集可 达 ( yxmapjiapyxmapyxji。我们采用动态程序设计的方法计算起点(x1,y1)至终点(x2,y2)的路径数目mapx2,y2:阶段 j:中国象棋马当前的列位置(y1jy2);状态 i:中国象棋马在 j 列的行位置(1in) ;决策 k:中国象棋马在(i,j)的起跳方向(1k4);计算过程如下:fillchar(map,sizeof(map),0);mapx1,y1 1; 从(x1,y1)出发for jy1 to y2 do 递推中国象棋马的列位置for i1 to n do 递推中国象棋马在 j 列的行位置for k1 to 4 do 递推中国象棋马在(i,j)的 4 个跳动方向begin中国象棋马由(i,j)出发,沿着 k 方向跳至(x,y) ;if (xn )(y1y2) 计算状态转移方程then mapx,y mapi,j+mapx,yend;forwriteln(mapx2,y2:0:0); 输出从(x1,y1)到(x2,y2)的路径数目上述算法的时间复杂度为 O(n 2) ,明显优于回溯法的效率。