1. 程式人生 > >bzoj 4710(組合數學+容斥原理)

bzoj 4710(組合數學+容斥原理)

傳送門
題解:
先介紹一條公式:將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); }