路径数的计算
问题:编制程序,计算从点A(0,0)到点B(m,n)的路径数。行走方向只能向上或向右。
+--+--+--+--+--+B(m,n)
| | | | | |
+--+--+--+--+--+
| | | | | |
+--+--+--+--+--+
| | | | | |
+--+--+--+--+--+
A(0,0)
一条从A到B的路径将有m次向右行走和n次向上行走。如果将向右行走标记为0,将向上行走标记为1,则一条从A到B的路径对应一个长度为m+n的0-1串,其中含m个0和n个1,例如,下面的路径
+--+--+--+--****B(m,n)
| | | | * |
+--+--+--+--*--+
| | | | * |
+--**********--+
| * | | | |
****--+--+--+--+
对应的0-1串为:01000110
因此,路径数=长度为m+n的0-1串的个数(m个0,n个1),其值为(m+n)!/m!n!,即C(m+n,m)(表示一个二项式系数)。
这里我们考虑一下路径数的递推计算方法:一条从A到B的路径必经P(m-1,n)及Q(m,n-1)之一
P(m-1,n)
+--+--+--+--*--+B(m,n)
| | | | | |
+--+--+--+--+--*Q(m,n-1)
| | | | | |
+--+--+--+--+--+
| | | | | |
+--+--+--+--+--+
记从(0,0)到(m,n)的路径数为path(m,n),由加法原理,
path(m,n)=path(m-1,n)+path(m,n-1) (m,n>0)
且
path(0,n)=path(n,0)=1 (n>=0)
由此可得下面的计算程序:
for (y=0; y<=n; y++)
path[0][y]=1;
for (x=1; x<=m; x++)
{
path[x][0]=path[x-1][0];
for (y=1;y<=n; y++)
path[x][y]=path[x-1][y]+path[x][y-1];
}
用一个二维数组,可以计算出(0,0)到(m,n)的路径数。
~~~~~~~~~~
观察从x列推进到x+1列时的递推格式:
path[x][n] ---> path[x+1][n]
A
|
path[x][n-1] ---> path[x+1][n-1]
A
|
path[x][n-2] ---> path[x+1][n-2]
A
|
.
.
.
A
|
path[x][2] ---> path[x+1][2]
A
|
path[x][0] ---> path[x+1][1]
A
|
path[x][1] ---> path[x+1][0]
由于计算path[x+1][k]时只需要用到path[x][k]及path[x+1][k-1]的值,即path[x+1][k]只用到第x行一个值,且该值在递推第x+1行的过程中仅仅用到一次,因此,我们可以只用一个一维数组p[]来进行路径数的计算,开始时,该数组保存x=0列的所有路径数
for (y=0; y<=n; y++)
path[y]=1;
在从第x列递推到第x+1列时,我们从y=0到n进行递推,当y=0时,path[y]的值不变,而当y>0时有:
for (y=1; y<=n, y++)
path[y] += path[y-1];
这样,按上述递推关系推经到x=m的行后,path[n]即为路径数。
完整的算法为:
for (y=0; y<=n; y++)
path[y]=1;
for (x=1; x<=m; x++)
for (y=1; y<=n, y++)
path[y] += path[y-1];
算法的时间复杂性为O(mn)。
~~~~~~~~~~
利用上述递推计算的思想,可以解决一些趣味数学中的问题,例如:
问题一、计算下图中从A到B的路径数。
+--+--+--+--+--+B(m,n)
| | | | | |
+--+--+--+--+--+
| | | |
+--+ +--+
| | | |
+--+ +--+
| | | |
+--+--+--+--+--+
| | | | | |
+--+--+--+--+--+
A(0,0)
利用基本递推关系,可以得到:
1--6--11-16-26-52
| | | | | |
1--5--5--5--10-26
| | | |
1--4 5--16
| | | |
1--3 5--11
| | | |
1--2--3--4--5--6
| | | | | |
1--1--1--1--1--1
问题二、计算下图中从A到B的路径数
+---+---+---+---+---+B
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
A
同样利用基本的递推关系可以得到:
20--75--186-353-576-855
| | | | | |
20--55--111-167-223-279
| | | | | |
1---4---10--20--35--56--56--56--56
| | | | | |
1---3---6---10--15--21
| | | | | |
1---2---3---4---5---6
| | | | | |
1---1---1---1---1---1