计算组合数(高精度)


import java.util.ArrayList;

public class LongInt {
    
    
    private static final int Warp = 10000;
    private static final ArrayList<Integer>[][] d = new ArrayList[202][102];

    public static void main(String[] args) throws Exception {
    
    

        for (int i = 0; i <= 200; i++) {
    
    
            for (int j = 0; j <= 100; j++) {
    
    
                d[i][j] = new ArrayList<>(20);
            }
        }
        int N = 200, M = 100, K = 38;

        C(N, M);
        C(N - M, K - 1);
        C(M, M - (K - 1));

        ArrayList<Integer> ret = mul(d[N - M][K - 1], d[M][M - (K - 1)]);
        print(ret);
        System.out.print('/');
        print(d[N][M]);
        System.out.println();
    }
    //dfs for 组合数
    private static ArrayList<Integer> C(int n, int m) {
    
    
        if (d[n][m].size() > 0) return d[n][m];
        if (m == 1) {
    
    
            d[n][m].add(n);
            return d[n][m];
        }
        if (n == m) {
    
    
            d[n][m].add(1);
            return d[n][m];
        }
        if (n == 1 || m == 0) {
    
    
            d[n][m].add(1);
            return d[n][m];
        }
        C(n - 1, m - 1);
        C(n - 1, m);
        sum(new int[]{
    
    n - 1, m - 1}, new int[]{
    
    n - 1, m}, new int[]{
    
    n, m});
        return d[n][m];
    }

    private static void sum(int[] n, int[] m, int[] r) {
    
    
        ArrayList<Integer> ret = d[r[0]][r[1]];
        ArrayList<Integer> an = d[n[0]][n[1]];
        ArrayList<Integer> am = d[m[0]][m[1]];
        int carry = 0, i = 0, j = 0, idx = 0;
        int e1 = an.size(), e2 = am.size();

        int temSum;
        while (i < e1 && j < e2) {
    
    
            temSum = an.get(i++) + am.get(j++) + carry;
            carry = temSum / Warp;
            ret.add(idx++, temSum % Warp);
        }

        while (i < e1) {
    
    
            temSum = an.get(i++) + +carry;
            carry = temSum / Warp;
            ret.add(idx++, temSum % Warp);
        }

        while (j < e2) {
    
    
            temSum = am.get(j++) + carry;
            carry = temSum / Warp;
            ret.add(idx++, temSum % Warp);
        }

        while (carry > 0) {
    
    
            temSum = carry + (idx >= ret.size() ? 0 : ret.get(idx));
            carry = temSum / Warp;
            ret.add(idx++, temSum % Warp);
        }
    }

    private static ArrayList<Integer> mul(ArrayList<Integer> as, ArrayList<Integer> bs) {
    
    
        int[] ret = new int[20];
        int aLen = as.size();
        int bLen = bs.size();
        for (int i = 0; i < bLen; i++) {
    
    
            for (int j = 0; j < aLen; j++) {
    
    
                ret[i + j] += as.get(j) * bs.get(i);
                ret[i + j + 1] += ret[i + j] / Warp;
                ret[i + j] %= Warp;
            }
        }
        ArrayList<Integer> d = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
    
    
            d.add(ret[i]);
        }
        return d;
    }

    static void print(ArrayList<Integer> ret){
    
    
        boolean isStart = false;
        for (int i = ret.size() - 1; i >= 0; i--) {
    
    
            if (ret.get(i) == 0 && !isStart) continue;
            if (isStart) System.out.printf("%04d", ret.get(i));
            else System.out.print(ret.get(i));
            isStart = true;
        }
    }
}


猜你喜欢

转载自blog.csdn.net/awp0011/article/details/103888362