我想计算nCr modulo 142857
。以下是我在Java中的代码:
private static int nCr2(int n, int r) {
if (n == r || r == 0) {
return 1;
}
double l = 1;
if (n - r < r) {
r = n - r;
}
for (int i = 0; i < r; i++) {
l *= (n - i);
l /= (i + 1);
}
return (int) (l % 142857);
}
这会在O(r)
时间内提供nCr。我想要一个算法来获得比这更短的时间的结果。有这样的算法吗?
答案 0 :(得分:1)
您可以预先计算给定n
和r
对的结果,并在表int t[][]
中对其进行硬编码。
稍后,在运行时,当您需要nCr(n, r)
时,您只需查看此表:t[n][r]
。
在运行时这是O(1)
。
答案 1 :(得分:1)
由于您的号码不是素数,this answer不适用。但您可以轻松地将142857分解为素数,计算相应的模数,并使用Chinese Remainder Theorem得到结果。对于您正在使用的数字,这可能有意义也可能没有意义。
在任何情况下你都必须避免加倍,除非你可以确定所有的中间结果只能用53位精确表示(否则你就会失去精确度并且无法理解)。
答案 2 :(得分:0)
您已经在所提及的功能中获得了大部分答案。如果n是固定的且r是可变的,则可以使用nCr = nC(r-1)*(n - r + 1)/ r。因此,您可以使用nCr表并逐步构建(不像其他答案提到预计算不是增量的那样)。
因此,您的新函数可以通过传递的表进行递归。