版權聲明:本文為CSDN博主「梵解君」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/hadeso/article/details/12622743
--------------------------------------------------------------------------------------------------------------------
解法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(i, j)的狀態轉移方程為:

遞歸結束條件為:f(0,0)=0, f(0,1)=1, f(1,0)=1。這個問題可以在時間O(n^2),空間O(n^2)內求解。
遞歸解法
//遞歸解法
int process(int m, int n) {
//永遠不可能達到m & n同時為0的條件,除非輸入m=n=0
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)的組合數。
