java - 使用 modInverse 计算大数的 C(n, k) 组合

标签 java algorithm combinations combinatorics modular-arithmetic

我想计算组合C(n, k),其中nk可能非常大。我尝试通过使用模块化逆来做到这一点,如下所示,但即使对于小数字,它也不会给出正确的输出。谁能告诉我哪里错了?

import java.math.BigInteger;

public class Test {

    public static int[] factorials = new int[100001];
    public static int mod = 1000000007;
    public static BigInteger MOD = BigInteger.valueOf(1000000007);

    public static void calculateFactorials() {

        long f = 1;

        for (int i = 1; i < factorials.length; i++) {
            f = (f * i) % mod;
            factorials[i] = (int) f;
        }

    }

    // Choose(n, k) = n! / (k! * (n-k)!)
    public static long nCk(int n, int k) {

        if (n < k) {
            return 0;
        }

        long a = BigInteger.valueOf(k).modInverse(MOD).longValue();
        long b = BigInteger.valueOf(n - k).modInverse(MOD).longValue();

        // Left to right associativity between * and %
        return factorials[n] * a % mod * b % mod;

    }

    public static void main(String[] args) {

        calculateFactorials();
        System.out.println(nCk(5, 2));

    }

}

最佳答案

线条

    long a = BigInteger.valueOf(k).modInverse(MOD).longValue();
    long b = BigInteger.valueOf(n - k).modInverse(MOD).longValue();

应该是

    long a = BigInteger.valueOf(factorials[k]).modInverse(MOD).longValue();
    long b = BigInteger.valueOf(factorials[n - k]).modInverse(MOD).longValue();

您可以考虑缓存逆阶乘和阶乘。

关于java - 使用 modInverse 计算大数的 C(n, k) 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25356014/

相关文章:

php - 使用来自 3 个平面数组的所有值组合形成分隔字符串数组

artificial-intelligence - 最相距的 k 个元素(聚类?)

java - 将现有图像添加到 Canvas

python - Minimax 算法 tic tac toe 不工作

java - 使用 Grid Bag Layout 调整按钮大小

c++ - 如何在结构体的 `std::list`处进行搜索?

java - 寻找 double 子集的有效算法和子集在一起

c - 循环所有数字组合

java - SomeClass<Object> 什么时候合适/有用

java - 如何根据模式拆分字节数组?