簡體   English   中英

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

[英]Calculate nCr(n,m) mod k for large n efficiently

我需要有效地計算大nn <= 10^7) nCr(n,m) % 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;
}

它通過利用pascals身份來計算mod k: nCr(n,m) % k的一些組合量。

這對於大n來說效率太低(嘗試choose(100, 12, 223092870) ),我不確定這是否可以通過記憶加速或者是否需要一些完全不同的數理論方法來加速。

我需要立即高效地執行此操作,這就是為什么我不確定memoization是否是解決方案。

注意: k不一定是素數!

由於nPr有一個明確的公式nPr(n, m) = n!/((nm)!)你一定要嘗試使用它。 我的提示是:

  • 記住那個! = n *(n-1)* ... * 2 * 1
  • 請注意, while循環 (是的,循環,而不是遞歸^^)可以極大地優化計算(除法取消了很多因子,讓你得到乘法nPr(n, m) = n*(n-1)*...*(n-m+2)*(n-m+1)

最后,您應該計算nPr(n,m) 計算模數,以避免冗余模運算。

如果它有幫助,你可以嘗試制定一個循環不變量 ,這幾乎是一個聲明,對於nm所有有效值都應該是真的。

希望這有助於:)

編輯

在我寫完答案后,我意識到你說過nCr。 對於nCr,您可以在計算nPr后添加另一個while循環,它只是計算m! ,將nPr除以m! ,然后以模數回答。 總而言之,這將產生一個O(n)算法,該算法非常可擴展。 它也使用非常少的內存。

這在編程競賽中不時出現,解決這個問題的一種常見方法是使用Lucas和中國剩余定理。

@DAle發布了一個有用的資源,其中包含詳細信息: http ://fishi.devtail.io/weblog/2015/06/25/computing-large-binomial-coefficients-modulo-prime-non-prime/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM