bzoj 4710(組合數學+容斥原理)
阿新 • • 發佈:2019-01-22
傳送門
題解:
先介紹一條公式:將n個物品分給m個人有C(n+m-1,m-1)種方案。但是這些方案是包括了不合法的(有些人沒有獲得任何物品)。對於這道題,需要保證所有人都分到物品,所以容斥原理解決:
ans=0個人沒分到-1個人沒分到+2個人沒分到……n個人沒分到
對於某一種情況——i個人沒分到:
當前方案數=n個人選i個人方案數*每種物品都分給(n-i)個人的方案數(就是程式碼中now的含義)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1002;
const int MOD=1e9+7;
int n,m,c[MAXN<<1][MAXN<<1],a[MAXN];
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=m;++i) scanf("%d",&a[i]);
for (int i=0;i<=2000;++i) c[i][0]=1;
for (int i=1;i<=2000;++i)
for (int j=1;j<=2000;++j)
c[i][j]=(c[i-1][j-1]+c[i-1 ][j])%MOD;
ll ans=0;
for (int i=0,f=1;i<=n;++i,f=-f) {
ll now=1;
for (int j=1;j<=m;++j)
now=now*c[a[j]+n-i-1][n-i-1]%MOD;
ans=(ans+now*c[n][i]%MOD*f)%MOD;
}
printf("%lld\n",(ans%MOD+MOD)%MOD);
}