[BZOJ4710][Jsoi2011]分特產(容斥原理+組合數學)
阿新 • • 發佈:2018-12-30
題目描述
題解
這道題的限制其實挺不明顯的,應該是“每個人都至少有一個”
也就是說對於所有的物品,將其劃分成n部分,每部分不能為空,問總的方案數
可以如果利用插板法的話,把n個相同的小球放到m個不同的盒子裡有
根據容斥原理,答案應該為至少0個盒子為空的-至少1個盒子為空的+至少2個盒子為空的-…至少n個盒子為空的
那麼我們可以每一次強制i個盒子為空,剩餘的再像上面一樣選就行了
程式碼
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define Mod 1000000007
#define LL long long
int n,m,a[1005],c[2005][2005];
LL ans;
int main()
{
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]+c[i-1][j-1])%Mod;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;++i) scanf("%d",&a[i]);
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;
}
ans=(ans%Mod +Mod)%Mod;
printf("%lld\n",ans);
}