题面
题意:m种物品,第i种有
bi
b
i
个
分给n个小朋友,问方案数
设 f[i] f [ i ] 为在n个中枚举i个没拿,剩下的随便的方案数
对于一种恰好有i个没拿的方案,在 f[x] f [ x ] 中算了 Cix次 C x i 次
设
g[i]
g
[
i
]
为恰好选了i个的方案数
就有
反演过来有
g[0] g [ 0 ] 为答案
考虑算 f f ,每种物品是独立的,乘起来即可
对于每种就是
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))
typedef long long LL;
const int N=2020;
const LL p=1e9+7;
int n,m;
LL jc[N],Ijc[N],I[N];
LL f[N],ans;
int b[N];
LL C(int x,int y)
{
if(x<y)
return 0;
return jc[x]*Ijc[y]%p*Ijc[x-y]%p;
}
int main()
{
I[1]=jc[0]=Ijc[0]=1;
for(int i=2;i<N;i++)
I[i]=I[p%i]*(p-p/i)%p;
for(int i=1;i<N;i++)
jc[i]=jc[i-1]*i%p,Ijc[i]=Ijc[i-1]*I[i]%p;
cin>>n>>m;
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
for(int i=0;i<=n;i++)
{
f[i]=C(n,i);
for(int j=1;j<=m;j++)
f[i]=f[i]*C(n-i-1+b[j],b[j])%p;
}
for(int i=0;i<=n;i++)
if(i%2==1)
ans=(ans-f[i]+p)%p;
else
ans=(ans+f[i])%p;
cout<<ans<<endl;
return 0;
}