30.BZOJ4710 容斥定理+相互独立+组合模型 跟6类似
题意:M种颜色的球,每种球有Mi个,放入N个不同的盒子里,不可以空盒
问方案数 M,N,Mi<=1000
思路:考虑容斥 Ai为第i个盒子是空盒
ans=|非A1∩非A2∩非A3|=|S|-sum|Ai|+sum|Ai∩Aj|-sum|Ai∩Aj∩Ak|
sum|Ai|=C(n,1)*【剩下n-1个盒可以为空的方案数】
sum|Ai∩Aj|=C(n,2)*【剩下n-2个盒可以为空的方案数】
【】是子问题:M种颜色的球,每种球有Mi个,放入N个不同的盒子里,可以空盒
注意到此时M种球之间相互独立!!!
所以每种球套相同球放不同盒子可以空盒模型,分别算一遍乘起来就好了
Ans=sum_{i=0~n-1}( (-1)^(n-1)*C[n][i]* mul_{j=1~m}C[Mi[j]+n-i-1][n-i-1] )
子问题↑
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int mi[1005];
int c[2005][2005];
void init()
{
c[0][0]=1;
for(int i=1;i<=2000;i++)c[i][0]=c[i][i]=1,c[i][1]=i;
for(int i=1;i<=2000;i++)
{
for(int j=1;j<=i;j++)
c[i][j]=1ll*(c[i-1][j-1]+c[i-1][j])%mod;
}
}
int main()
{
init();//printf("%d\n",c[5][2]);
int n,m;scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d",&mi[i]);
int ans=0;
for(int i=0;i<n;i++)
{
int tem=1;
for(int j=1;j<=m;j++)
{
tem=1ll*tem*c[mi[j]+n-i-1][n-i-1]%mod;
}
if(i%2==0)(ans+=1ll*c[n][i]*tem%mod)%=mod;
else ans=(ans-1ll*c[n][i]*tem%mod+mod)%mod;
}
printf("%d\n",ans);
}