C++ 计算n*n网格中从(0,0)到(n-1,n-1)的总路径
我使用一个简单的回溯算法来找到所有路径,但它没有给出正确的答案。我想不出这个错误。我们可以从一个给定的位置上下左右移动C++ 计算n*n网格中从(0,0)到(n-1,n-1)的总路径,c++,algorithm,backtracking,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
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);
}
}
Int路径(Int a[][200],Int n,Int m,Int r,Int c)
{
如果(n==r-1&&m==c-1){
返回1;
}
else如果(n>=r | | m>=c | | n<0 | | m<0){
返回0;
}
else如果(vis[n][m]==1){
返回0;
}
否则{
vis[n][m]=1;
int x=路径(a,n+1,m,r,c);
int y=路径(a,n,m+1,r,c);
int u=路径(a,n-1,m,r,c);
int v=路径(a,n,m-1,r,c);
vis[n][m]=0;
返回(x+y+u+v);
}
}
查找路径或计算路径并不完全相同。我假设您只想计算路径(因为您的问题的标题),并且您只能向右移动或向下移动
为此,您实际上不需要矩阵(表示网格)作为参数。以下是一个简单(尽管不是有效)的递归解决方案,也适用于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选择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);
}
}
查找路径或计算路径并不完全相同。我假设您只想计算路径(因为您的问题的标题),并且您只能向右移动或向下移动
为此,您实际上不需要矩阵(表示网格)作为参数。以下是一个简单(尽管不是有效)的递归解决方案,也适用于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选择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);
}
}
为什么需要编写程序来计算路径总数?它只是(2n!)/(n!)^2,不是吗?你能向后移动到左边吗?或者你只能向右移动和向下移动吗(这是通常问这个问题的方式)?我的排列和组合不是很强。只有向右和向下或所有四个方向?看它是
2n选择n
的方法是找出你必须总共做2n
步(n
down,n
right),然后从你选择的n
步中,而另一个n
则是正确的。为什么需要编写一个程序来计算路径总数?它只是(2n!)/(n!)^2,不是吗?你能向后移动到左边吗?或者你只能向右移动和向下移动吗(这是通常问这个问题的方式)?我的排列和组合不是很强。只有向右和向下或所有四个方向?看它是2n选择n
的方法是找出你必须总共做2n
步(n
down,n
right),然后从你选择的n
步中,另一个n
你说对了。这根本不能回答问题。这根本不能回答问题。