这个想法是从N * N矩阵的左上角移动到右下角,其中唯一允许的移动是向下或向右移动。不允许回溯。使用动态编程很简单,如以下geeks for geeks链接所示。我试图了解如何使用简单的排列和组合来实现相同的目的。我遇到了以下BetterExplained链接。他们要解决的问题肯定不匹配。有没有一种方法可以使用排列和组合找到解决方案?可以帮助我更好地了解解决方案的指针吗?
编辑1:
以下是 3X3 矩阵的示例,当我们进行动态编程时,它显示了从左上点到右下点的6种方式,仅当使用公式{ {1}}。但是我列出了20种从起点到目的地的到达方式,即2(N-1)!/ (N-1)!(N-1)!
,或者我对这个问题的理解有误,这是可行的,因为我们已经在最左上角的单元格中,并遍历到最右下角的单元格单元格,那么答案将是2N!/N!*N!
答案 0 :(得分:2)
有(n-1) among 2(n-1)
种方法可以使用您给出的规则遍历n*n
矩阵。
一个简单的解释:由于仅允许移动downward
或rightward
,因此路径的长度必须恰好为2(n-1)
。
更重要的是,在这条路径中,将有n-1
个移动downward
,还有n-1
个移动rightward
(这是从路径到达右下角的唯一可能方式左上角)。
因此,(n-1) among 2(n-1)
来自所有可能的方式来适应n-1
的移动,并在2(n-1)
的移动中向下执行。
答案 1 :(得分:1)
如果矩阵是正方形(N x N
),我相信可以按以下方式计算路径数,其中n = N - 1
:
from math import factorial
def number_of_paths(n):
return int(factorial(2 * n) / (factorial(n) ** 2))
至于为什么...那有点复杂。首先,不要考虑上下左右移动,而是将矩阵旋转45度,以便我们始终向下移动,但是选择向左还是向右。
我们的矩阵现在是位于其末端的菱形,并形成Pascal's triangle的中心。这意味着我们可以查看Pascal三角形底行中心处的binomial coefficient,它是矩阵尺寸的两倍-1。
我们使用二项式系数,因为对此的一种解释是它显示了我们可以选择到达那里的路径数。
例如,在3 x 3
情况下,2 * 3 - 1 = 5
:
[1] C(0,0)
[1 1] C(1,0), C(1,1)
[1 2 1] C(2,0), C(2,1), C(2,2)
1 [3 3] 1 C(3,0), C(3,1), C(3,1), C(3,1)
1 4 [!6!] 4 1 C(4,0), C(4,1), C(4,2), C(4,3), C(4,4)
Answer is 6! Answer is C(4, 2)!
答案是(2n)! / n! ** 2
(以下推导),我们可以直接计算出它。
您还可以通过在关心的底行中移动项目来将其推广为非平方矩阵,此时,您基本上只得到C(n, k)
。希望很清楚为什么。
只是数学!
从上图可以看到N的前三个值是:
N | Value
- + -------
1 | C(0, 0)
2 | C(2, 1)
3 | C(4, 2)
因此我们可以看到答案是:
= C(2(N - 1), N - 1)
let n = N-1
Given C(a, b) = a! / b!(a - b)!
= C(2n, n)
= (2n)! / n!(2n - n)!
= (2n)! / n! ** 2
路径长度的几何解释
想象一下4x4
矩阵的情况,尝试看看为什么长度为2(N-1)
。首先是一些观察结果:
首先,我们从左上方开始,没有任何动作,然后沿着顶部进行:
0 - - - 0 1 - - 0 1 2 - 0 1 2 3
- - - - > - - - - > - - - - > - - - -
- - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - -
经过3步移动后,我们遍历了长度4侧。因此,对于长度为N
的一面,需要N-1
来移动。垂直方向也是如此,这将需要我们再执行另一N-1
个移动才能从顶部到底部遍历:
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3
- - - - > - - - 4 > - - - 4 > - - - 4
- - - - - - - - - - - 5 - - - 5
- - - - - - - - - - - - - - - 6
因此,总路径长度为2(N-1)
答案 2 :(得分:0)
使用组合函数从am * n网格的左上角移动到右下角的总数为(n-1 + m-1)!/(n-1)!(m-1)!>
#include <iostream>
using namespace std;
int numberOfPaths(int m, int n)
{
// We have to calculate m+n-2 C n-1 here
// which will be (m+n-2)! / (n-1)! (m-1)!
int path = 1;
for (int i = n; i < (m + n - 1); i++) {
path *= i;
path /= (i - n + 1);
}
return path;
}
int main()
{
cout << numberOfPaths(3, 3);
return 0;
}
输出:6