给定一个M*N的格子或棋盘,从左下角走到右上角的走法总数(每次只能向右或向上移动一个方格边长的距离)

来源:互联网 发布:巨人网络 董事局 编辑:程序博客网 时间:2024/05/21 17:35
解法1:我们可以把棋盘的左下角看做二维坐标的原点(0,0),把棋盘的右上角看做二维坐标(M,N)(坐标系的单位长度为小方格的变长)   
用f(i,j)表示移动到坐标f(i,j)的走法总数,其中0=<i,j<=n,设f(m,n)代表从坐标(0,0)到坐标(m,n)的移动方法,则

f(m,n)=f(m-1,n)+f(m,n-1).

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

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

f(i,j)=f(i,j-1)            if i=0

f(i,j)=f(i-1,j)            if j=0

初始情况就为:f(0,0)=0, f(0,1)=1, f(1,0)=1,这个问题可以在时间O(n^2),空间O(n^2)内求解,非递归解.

/*
递归解
*/
int process(int m, int n) {    if (m == 0 && n == 0)        return 0;    if (m==0 || n==0)        return 1;    return process(m, n - 1) + process(m - 1, n);}

/*
非递归解
*/
int processNew(int m,int n){    int **Q=new int*[m+1];    for(int i=0; i<=m; ++i){        Q[i]=new int[n+1]();    }    //初始化    Q[0][0]=0;    for(int j=1; j<=n; ++j)        Q[0][j]=1;    for(int i=1; i<=m; ++i)        Q[i][0]=1;    //迭代计算    for(int i=1; i<=m; ++i){        for(int j=1; j<=n; ++j){            Q[i][j]=Q[i-1][j]+Q[i][j-1];        }    }    int res=Q[m][n];    delete [] Q;    return res;}

解法2:这个题目其实是一个组合问题。对方向编号,向上是0,向右是1,那么从左下角走到右上角一定要经过M 个1和N个0。这个题目可以转化为从M+N个盒子中挑出M个盒子有多少种方法。
就是C(M+N, M),或者C(M+N, N)。


原创粉丝点击