bzoj 4710: [Jsoi2011]分特产 排列组合+容斥原理

题意

JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们。JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望任何一个同学因为没有拿到特产而感到失落,所以每个同学都必须至少分得一个特产。例如,JYY 带来了2 袋麻花和1 袋包子,分给A 和B 两位同学,那么共有4 种不同的分配方法:
A:麻花,B:麻花、包子
A:麻花、麻花,B:包子
A:包子,B:麻花、麻花
A:麻花、包子,B:麻花
N, M 不超过1000,每一种特产的数量不超过1000
答案模1e9+7。

分析

只要用全部方案-至少有一个人没有特产的方案+至少有两个人没有特产的方案。。。即可

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

const int N=2005;
const int MOD=1000000007;

int n,m,a[N],ny[N],jc[N];

int ksm(int x,int y)
{
    int ans=1;
    while (y)
    {
        if (y&1) ans=(LL)ans*x%MOD;
        x=(LL)x*x%MOD;y>>=1;
    }
    return ans;
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++) scanf("%d",&a[i]);
    ny[0]=jc[0]=1;
    for (int i=1;i<=2000;i++) jc[i]=(LL)jc[i-1]*i%MOD,ny[i]=ksm(jc[i],MOD-2);
    int ans=0;
    for (int i=0;i<=n-1;i++)
    {
        int w=(LL)jc[n]*ny[i]%MOD*ny[n-i]%MOD;
        for (int j=1;j<=m;j++) w=(LL)w*jc[n-i+a[j]-1]%MOD*ny[n-i-1]%MOD*ny[a[j]]%MOD;
        if (i%2==0) (ans+=w)%=MOD;
        else (ans-=w)%=MOD;
    }
    printf("%d",(ans+MOD)%MOD);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值