我遇到了一个问题,要求在二维坐标平原上找到从第1点到第2点的独特方式。
注意:可以假设x1 < x2
和y1 < y2
而不失一般性。
此外,动作受到以下方式的限制。一个人只能向右或向上移动。表示如果(xa, ya)
和(xb, yb)
,则有效移动从xa < xb
到ya < yb
。
数学上,这可以通过( [(x2-x1)+(y2-y1)]! ) / [(x2-x1)!] * [(y2-y1)!]
找到。我也想过代码。
我有使用动态编程编码的方法,我的方法需要大约O([max(x2,y2)]^2)
时间和Theta( x2 * y2 )
,我可以使用上三角矩阵或下三角矩阵进行管理。
您能想到其他一些运行时间少于此的方法吗?我正在考虑递归解决方案,其最短运行时间为O(max(x2,y2))
。
答案 0 :(得分:1)
一个简单有效的解决方案是数学解决方案。
允许x2-x1 = n
和y2-y1 = m
。
您需要向右迈出n
步,m
步骤,所有剩下的就是确定他们的顺序。
这可以建模为具有n+m
个元素且精确n
个元素设置为1的二进制向量的数量。
因此,可能性总数为chose(n,n+m) = (n+m)! / (n! * m!)
,这正是你得到的。
鉴于数学答案已得到证实并且计算速度更快 - 我认为没有理由使用具有这些限制的不同解决方案。
如果你渴望在这里使用递归,recursive formula for binomial coefficient可能会很适合。
修改强> 您可能正在寻找multiplicative formula来计算它。
答案 1 :(得分:0)
要计算答案,您可以使用以下公式:
(n+m)!/(n!m!)=(n+1)*(n+2)/2*(n+3)/3*…*(n+m)/m
所以伪代码是:
let foo(n,m) =
ans=1;
for i = 1 to m do
ans = ans*(n+i)/i;
done;
ans
乘法和除法的顺序很重要,如果修改它,即使结果不是很大,也会有溢出。
答案 2 :(得分:0)
我终于设法撰写文章来详细描述这个问题并完成答案。这是相同的链接。 http://techieme.in/dynamic-programming-distinct-paths-between-two-points/
答案 3 :(得分:-2)
试试这个公式:
ans = (x2-x1) * (y2-y1) + 1;