XTU online judge 1177 Grid

Description
一个N*M的网格,从左下角沿格子线走到右上角,只能往右或者往上走,请问有多少种不同的路线?

Input
多个样例,每行包含两个整数N,M(1≤N,M≤33);如果N和M为0表示输入结束。

Output
每个样例输出一行,为路线的数目。

Sample Input
1 1
1 2
33 33
0 0

Sample Output
2
3
7219428434016265740

解法一

我们可以把棋盘的左下角看做二维坐标的原点(0,0),把棋盘的右上角看做二维坐标(N,M)(坐标系的单位长度为小方格的变长)。
用f(i,j)表示移动到坐标f(i,j)的走法总数,0=<i,j<=n,设f(n,m)代表从坐标(0,0)到坐标(n,m)的移动方法,则
f(n,m)=f(n-1,m)+f(n,m-1).

于是状态f(i,j)的状态转移方程为:

ifResult
i,j>0f(i,j)=f(i,j-1)+f(i-1,j)
i=0f(i,j)=f(i,j-1)
j=0f(i,j)=f(i-1,j)

初始情况为:f(0,0)=0, f(0,1)=1, f(1,0)=1,这个问题分别求递归解和非递归解。

递归解:

int process(int n, int m) 
{
    if(n == 0&&m == 0)
        return 0;
    if(n==0||m==0)
        return 1;
    return process(n,m-1)+process(n-1,m);
}

非递归解:

#include <stdio.h>
int main()
{
    unsigned __int64 f[67][67];
    int i,j;
    f[0][0] = 1;
    f[1][0] = 1;
    f[1][1] = 1;
    for(i=2;i<=66;i++)
    {
        f[i][0] = 1;
        for(j=1;j<i;j++)
        {
            f[i][j] = f[i-1][j]+f[i-1][j-1];
        }
        f[i][j] = 1;
    }
    while(scanf("%d %d",&i,&j)&&i+j!=0)
    {
        printf("%I64u\n",f[i+j][i]);
    }
    return 0;
}

解法二

这个题目也可以看做是一个组合问题。对方向编号,向上是0,向右是1,那么从左下角走到右上角一定要经过N 个1和M个0。这个题目可以转化为从M+N个盒子中挑出N个盒子有多少种方法。
就是C(M+N,,M),或者C(M+N,,N)。
所以2 * 2的格子有C(2+2, 2)=6中走法, 2* 3 的格子有 C(5, 2)=10种走法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值