计算nCr模142857的最有效方法

时间:2013-11-06 17:30:26

标签: java algorithm

我想计算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。我想要一个算法来获得比这更短的时间的结果。有这样的算法吗?

3 个答案:

答案 0 :(得分:1)

您可以预先计算给定nr对的结果,并在表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表并逐步构建(不像其他答案提到预计算不是增量的那样)。

因此,您的新函数可以通过传递的表进行递归。