JYY 帶隊參加了若干場ACM/ICPC 比賽,帶回了許多土特產,要分給實驗室的同窗們。c++
JYY 想知道,把這些特產分給N 個同窗,一共有多少種不一樣的分法?固然,JYY 不但願任spa
何一個同窗由於沒有拿到特產而感到失落,因此每一個同窗都必須至少分得一個特產。code
例如,JYY 帶來了2 袋麻花和1 袋包子,分給A 和B 兩位同窗,那麼共有4 種不一樣的ip
分配方法:input
A:麻花,B:麻花、包子it
A:麻花、麻花,B:包子io
A:包子,B:麻花、麻花ast
A:麻花、包子,B:麻花class
輸入數據第一行是同窗的數量N 和特產的數量M。方法
第二行包含M 個整數,表示每一種特產的數量。
N, M 不超過1000,每一種特產的數量不超過1000
輸出一行,不一樣分配方案的總數。因爲輸出結果可能很是巨大,你只須要輸出最終結果
MOD 1,000,000,007 的數值就能夠了。
5 4
1 3 3 5
384835
首先若是能夠有人不拿到就很好作
那麼就能夠考慮容斥
用\(f_i\)表示有i我的分包裹而且每一個人都拿到的方案數
而後簡單容斥就能夠了
#include<bits/stdc++.h> using namespace std; const int N = 2010; const int Mod = 1e9 + 7; int n, m, a[N], f[N]; int fac[N], inv[N]; int add(int a, int b) { return (a += b) >= Mod ? a - Mod : a; } int sub(int a, int b) { return (a -= b) < 0 ? a + Mod : a; } int mul(int a, int b) { return 1ll * a * b % Mod; } int fast_pow(int a, int b) { int res = 1; while (b) { if (b & 1) res = mul(res, a); b >>= 1; a = mul(a, a); } return res; } int C(int a, int b) { return mul(fac[a], mul(inv[a - b], inv[b])); } int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) scanf("%d", &a[i]); fac[0] = inv[0] = 1; for (int i = 1; i < N; i++) fac[i] = mul(fac[i - 1], i); inv[N - 1] = fast_pow(fac[N - 1], Mod - 2); for (int i = N - 2; i >= 1; i--) inv[i] = mul(inv[i + 1], i + 1); f[1] = 1; for (int i = 2; i <= n; i++) { int cur = 1; for (int j = 1; j <= m; j++) { cur = mul(cur, C(i + a[j] - 1, i - 1)); } for (int j = 1; j < i; j++) { cur = sub(cur, mul(C(i, j), f[j])); } f[i] = cur; } printf("%d", f[n]); return 0; }