UVa 10458 - Cricket Ranking (容斥)

題意

讓幾個區間內的數的和爲K,問方法數。

思路

組合數學P169。

代碼

import java.io.*;
import java.math.*;
import java.util.*;

public class Main {

    static BigInteger C(long n, long m) {
        if (n < m) return BigInteger.ZERO;
        m = Math.min(m, n-m);
        BigInteger cur_ans = BigInteger.ONE;
        for (int i = 0; i < m; i++) cur_ans = cur_ans.multiply(BigInteger.valueOf(n-i)).divide(BigInteger.valueOf(i+1));
        return cur_ans;
    }

    static int[] x, y;
    static int n, m;

    static void Solve() {
        BigInteger ans = BigInteger.ZERO;
        BigInteger add = BigInteger.ZERO, del = BigInteger.ZERO;
        for (int i = 0; i < (1<<n); i++) {
            long cnt = 0, cur_m = m;
            for (int j = 0; j < n; j++) {
                if (((1<<j)&i) != 0) {
                    cnt++;
                    cur_m -= y[j]+1;
                }
            }
            if (cur_m < 0) continue;
            if (cnt%2 == 0) add = add.add(C(cur_m+n-1, cur_m));
            else del = del.add(C(cur_m+n-1, cur_m));
        }
        System.out.println(add.subtract(del));
    }

    public static void main(String args[]) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            x = new int[100]; y = new int[100];
            n = in.nextInt(); m = in.nextInt();
            for (int i = 0; i < n; i++) {
                x[i] = in.nextInt();
                m -= x[i];
                y[i] = in.nextInt();
                y[i] -= x[i];
            }
            if (m < 0) System.out.println(0);
            else if (m == 0) System.out.println(1);
            else Solve();
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章