有效地计算大n的nCr(n,m)mod k

时间:2017-06-29 16:14:13

标签: java performance dynamic-programming number-theory

我需要有效地为;WITH CTE AS ( SELECT Name ,min([Issue Close Date]) as FirstIssueCloseDate FROM yourtable GROUP BY Name) SELECT * FROM yourtable A JOIN CTE B on a.name = b.name and a.[Issue Open Date] <= b.FirstIssueCloseDate nCr(n,m) % k计算n

这是我的尝试:

n <= 10^7)

通过利用pascals identity计算mod k:int choose(int n, int m, int k) { if (n==m || m==0) return 1 % k; return (choose(n-1, m-1, k) + choose(n-1, m , k)) % k; } 的一些组合数量。

这对于大型nCr(n,m) % k来说效率太低(尝试n),我不确定memoization是否可以加速这种情况,或者是否有一些完全不同的数字理论方法有必要的。

我需要立即高效地执行此操作,这就是为什么我不确定memoization是否是解决方案。

注意:choose(100, 12, 223092870)不一定是素数!

2 个答案:

答案 0 :(得分:1)

由于nPr有一个明确的公式nPr(n, m) = n!/((n-m)!),你一定要尝试使用它。我的提示是:

  • 记住那个! = n *(n-1)* ... * 2 * 1
  • 请注意, while循环(是的,循环,而不是递归^^)可以极大地优化计算(除法取消了很多因素,让你得到乘法nPr(n, m) = n*(n-1)*...*(n-m+2)*(n-m+1)

最后,你应该在计算nPr(n,m)之后计算模,以避免多余的模运算。

如果有帮助,您可以尝试制定loop invariant,这对于nm的所有有效值都应该是真实的。

希望这有助于:)

修改

我在写完答案后意识到你说过nCr。对于nCr,您可以在计算nPr后添加另一个while循环,只需计算m!,将nPr除以m!,然后以模拟THAT答案。总而言之,这将产生一个O(n)算法,该算法非常可扩展。它也使用非常少的内存。

答案 1 :(得分:0)

这在编程比赛中不时出现,解决这个问题的一种常见方法是使用卢卡斯和中国剩余定理。

@DAle发布了一个有用的资源,其中包含详细信息:http://fishi.devtail.io/weblog/2015/06/25/computing-large-binomial-coefficients-modulo-prime-non-prime/