30.BZOJ4710 容斥定理+相互独立+组合模型

版权声明:欢迎转载 https://blog.csdn.net/animalcoder/article/details/82504669

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] )

扫描二维码关注公众号,回复: 3573015 查看本文章

                                                                         子问题↑

#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);
} 

猜你喜欢

转载自blog.csdn.net/animalcoder/article/details/82504669