您的位置:首页 > Web前端 > JavaScript

[BZOJ4710]4710: [Jsoi2011]分特产 容斥原理+组合数学

2017-09-01 18:42 387 查看
Description

JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们。

JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法?当然,JYY 不希望任

何一个同学因为没有拿到特产而感到失落,所以每个同学都必须至少分得一个特产。

例如,JYY 带来了2 袋麻花和1 袋包子,分给A 和B 两位同学,那么共有4 种不同的

分配方法:

A:麻花,B:麻花、包子

A:麻花、麻花,B:包子

A:包子,B:麻花、麻花

A:麻花、包子,B:麻花

题解:

这篇博客写得很清楚明白:zyf2000

下面说的是帮助一下排列组合比较弱的同学,大神可以不用看:

把n个相同的小球放到m个不同的盒子里有Cm−1n+m−1种方案,就是再增加n个小球,然后在其中插板,这样的话每堆至少有一个,再每堆拿掉一个,就符合要求了。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
const LL mod=10000
1043e
00007;
const int maxn=1010;
int n,m,a[maxn];
LL C[maxn*2][maxn*2],ans=0;
void pre()
{
C[0][0]=1;
for(int i=1;i<=maxn*2-15;i++)
{
C[i][0]=1;
for(int j=1;j<=i;j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
LL calc(int x)
{
int nn=n-x;
LL re=1;
for(int i=1;i<=m;i++)
re=(re*C[a[i]+nn-1][nn-1])%mod;
return re;
}
int main()
{
pre();
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d",&a[i]);
for(int i=0;i<n;i++)
{
LL t=calc(i)*C
[i]%mod;
if(i&1)ans=(ans-t+mod)%mod;
else ans=(ans+t)%mod;
}
printf("%lld",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: