路径数的计算

路径数的计算


问题:编制程序,计算从点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


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值