计算n * n网格中从(0,0)到(n-1,n-1)的总路径

时间:2015-07-04 19:56:29

标签: c++ algorithm backtracking

我使用简单的回溯算法来查找所有路径,但它没有给出正确的答案。我无法弄清楚错误。我们可以从给定的位置向上,向下,向左和向右移动。

    Int path(int a[][200],int n,int m,int r,int c) 
    {
        if(n == r - 1 && m == c-1) {
            return 1;
        }
        else if(n >= r || m >= c || n < 0 || m < 0) {
            return 0;
        }
        else if(vis[n][m] == 1) {
            return 0;
        }
        else {
            vis[n][m] = 1;
            int x = path(a,n+1,m,r,c);
            int y = path(a,n,m+1,r,c);
            int u = path(a,n-1,m,r,c);
            int v = path(a,n,m-1,r,c);
            vis[n][m] = 0;
            return (x+y+u+v);
        }
}

1 个答案:

答案 0 :(得分:0)

找到路径计算路径并不完全相同。我假设您只想计算路径(因为问题的标题),并且您只能向右移动向下移动

为此,您并不需要矩阵(表示网格)作为参数。以下是一个简单的(虽然效率不高)递归解决方案,也适用于n * m网格:

int countPaths(int m, int n) {
    if (m == 0 || n == 0)
        return 1;

    return countPaths(m-1, n) + countPaths(m, n-1); 
}

一般n * n网格的数学解法是:

(2n choose n) = (2*n)!/(n!*n!)

然后,将结果与公式进行比较:

countPaths(1, 1) == 2   // (2*1)!/(1!*1!)=2

countPaths(2, 2) == 6   // (2*2)!/(2!*2!)=6

countPaths(3, 3) == 20  // (2*3)!/(3!*3!)=20

您的回溯方法会给出相同的结果,但需要考虑一些因素。例如,考虑何时n=2,您将需要一个3x3矩阵(通常为(n+1)x(n+1)矩阵)来表示/探索(并标记为1)2x2网格的所有路径:

int countPaths(int a[][3],int n, int m, int r, int c) {
        if(n == r-1 && m == c-1) {
            return 1;
        }
        else if(n >= r || m >= c || n < 0 || m < 0) {
            return 0;
        }
        else if(vis[n][m] == 1) {
            return 0;
        }
        else {
            vis[n][m] = 1;
            int x = countPaths(a,n+1,m,r,c);
            int y = countPaths(a,n,m+1,r,c);
            vis[n][m] = 0;
            return (x+y);
        }
} 

然后:

countPaths(vis, 0, 0, 3, 3) == 6  // (2*2)!/(2!*2!)=6