zoukankan      html  css  js  c++  java
  • 题解 [BZOJ4710] 分特产

    题面

    解析

    step 1

    我们先考虑下有人没有的情况吧,

    那对于每个特产就是放隔板的情况了,

    (a[i])为第(i)个特产的个数,

    那么第(i)个特产的方案数就是(C_{a[i]+n-1}^{n-1}),(这个不解释了吧)

    然后再根据乘法原理乘起来就行了:(prod_{i=1}^mC_{a[i]+n-1}^{n-1}).

    step 2

    但是要求每个人都要分到啊.

    而上面的式子是包含了有人没有的情况的.

    所以我们容斥一下就好了.

    (f[k])表示至少有(k)个人没有分到(也就是钦定(k)个人没有),

    那么方案数就是(f[k]=prod_{i=1}^mC_{a[i]+n-k-1}^{n-k-1}).

    最后来一个容斥:(ans=sum_{k=0}^{n-1}(-1)^kC_n^kf[k]),

    组合数是因为可以任意钦定(k)个人没有.

    code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define ll long long
    #define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
    using namespace std;
    
    inline int read(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    	return f*sum;
    }
    
    const int N=2001;
    const int Mod=1000000007;
    int n,m,a[N];
    ll c[N][N];
    ll f[N],ans;
    
    int main(){
    	n=read();m=read();
    	for(int i=0;i<N;i++) c[i][0]=1;
    	for(int i=1;i<N;i++)		
    		for(int j=1;j<N;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%Mod;
    	for(int i=1;i<=m;i++) a[i]=read();
    	for(int i=0;i<=n;i++) f[i]=1;
    	for(int i=0;i<n;i++)
    		for(int j=1;j<=m;j++) f[i]=(f[i]*c[a[j]+n-i-1][n-i-1])%Mod;	
    	for(int i=0;i<n;i++) ans=(ans+c[n][i]*f[i]%Mod*((i&1)? -1:1))%Mod;
    	printf("%lld
    ",(ans+Mod)%Mod);
    	return 0;
    }
    
    
  • 相关阅读:
    集合的笼统介绍之Collection
    集合的笼统介绍之ArrayList
    final关键字+static关键字+匿名对象
    多态
    练习018:搜索插入位置
    练习017:实现strStr()
    练习016:移除元素
    练习015:删除排序数组中的重复项
    练习014:合并两个有序链表
    用JS实现链表
  • 原文地址:https://www.cnblogs.com/zsq259/p/11181856.html
Copyright © 2011-2022 走看看