標籤:容斥原理
題目:Codeforces Round #258 (Div. 2)Devu and Flowers題意:n個boxes ,第i個box有fi個flowers,每個boxes中的flowers完全相同,不同boxes的flowers不同,求從n個boxes中取出s個flowers的方案數。n<=20,s<=1e14,fi<=1e12.排列組合的題目,一解法可用容斥原理(inclusion exclusion principle) 。有2中寫法dfs和集合。下為集合寫法。
#include <bits\stdc++.h>using namespace std;const int MOD = 1e9 + 7;typedef long long LL;LL invv[25];LL inv(LL x)/// 求逆元{ return x == 1 ? 1LL : (MOD - MOD / x) * inv (MOD % x) % MOD;}LL Cmn(LL n, LL m) ///求組合數{ LL ret = 1; for (int i = 1; i <= m; i++) ret = (n - i + 1) % MOD * ret % MOD * invv[i] % MOD; return ret;}int calc(int x){ int ret = 0; while (x) {// x -= x & (-x); x=x&(x-1); ret ^= 1; } return ret;}int n;LL s, a[25];int main(){ for (int i = 1; i < 25; i++) invv[i] = inv(i); cin >> n >> s; for (int i = 0; i < n; i++) cin >> a[i]; int ALL = (1 << n) - 1; LL ans = 0; for (int i = 0; i <= ALL; i++)///遍曆所有集合 { LL nows = s; int num = 0;///統計當前集合元素個數,以確定符號 for (int j = 0; j < n; j++) { if (i & (1 << j)) { nows -= a[j] + 1; num++; } } if (nows < 0) continue; if (num & 1)///集合含有奇數個元素,符號為- ans -= Cmn(nows + n - 1, n - 1); else///集合含有偶數個元素,符號為+ ans += Cmn(nows + n - 1, n - 1); ans %= MOD; } cout << (ans + MOD) % MOD << endl; return 0;}
Codeforces Round #258 (Div. 2)Devu and Flowers 容斥原理