题目链接:戳我

容斥题。

设\(f[i]\)表示至多有i个人能够分到(也就是至少n-i个人分不到)的方案数

\(f[i]=\prod_{j=1}^mC_{a[j]+i-1}^i-1\)

a[j]表示的是该特产的数量。

为什么组合数是那样子写的呢?大家考虑一下,a[j]个球,分成i份,每份可以为空是不是就是这样子写的呢?(当然大家也可以考虑一下如果不为空怎么写呢。。不会的话可以去看看数学选修2-3,不过当然,这个不在本题的讨论范围内啦)

然后根据容斥原理,我们知道每个人都至少有一个特产的方案数=至少有0个人没有-至少1个人没有+至少2个人没有。。。。。(等效于上面的至多嘛)

然后答案就是\(\sum_{i=1}^n(-1)^{n-i}C_n^if[i]\)啦

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
#define mod 1000000007
using namespace std;
int n,m;
int a[MAXN];
long long ans=0;
long long dp[MAXN],f[MAXN],C[2010][2010];
inline void init()
{
for(int i=0;i<=2000;i++) C[i][0]=1,C[i][i]=1;
for(int i=2;i<=2000;i++)
for(int j=1;j<i;j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]);
init();
for(int i=1;i<=n;i++) f[i]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
f[i]=1ll*f[i]*C[i+a[j]-1][i-1]%mod;
}
for(int i=1;i<=n;i++)
{
int op;
if((n-i)&1) op=-1;
else op=1;
ans=(ans+1ll*op*C[n][i]*f[i]+mod)%mod;
}
printf("%I64d\n",ans);
return 0;
}

最新文章

  1. 注解:【基于主键的】Hibernate1-&gt;1关联
  2. Channel
  3. Compare接口
  4. Struts2基础
  5. VisualSVN Server搭建VDFS分布式仓研究(未成功)
  6. Java实验二20135104
  7. chrome浏览器关闭标签页面
  8. Centos7关闭防火墙与selinux
  9. procps包里面的sysctl命令
  10. 20150618_Andriod _KSOAP2_多线程
  11. android:layout_weight越大所占比例越大和越大所占比例越小的两个例子
  12. linux学习笔记---未完待续,缓慢更新
  13. centos升级python到2.7
  14. 升级Xcode6.3插件失效解决办法
  15. Entitlements (授权机制) 延伸
  16. 笔记:利用Cocos2dx 3.3 lua 做一个动作类游戏(一)
  17. 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络GoogLeNet
  18. 结合实例分析Android MVP的实现
  19. 写写我的硕士三年【zz】
  20. 《DSP using MATLAB》Problem 6.6

热门文章

  1. 3DMAX 处理反面
  2. 【298】◀▶ IDL 系统过程&amp;函数
  3. 使用avalon 实现一个序列号功能
  4. 将maven打包为一个jar(可以体外加入jar)
  5. CBCentralManager Class 的相关分析
  6. Android开发实战之ViewPager的轮播
  7. 云计算 Restfull API 设计之旅
  8. Ubuntu14.04下opencv卸载与重装
  9. OpenGL坐标变换专题
  10. &#39;for&#39; loop initial declarations are only allo