【题目链接】
【算法】
考虑求每个人可以不分的方案
那么,对于每件物品,我们把它分成n份,每一份对应分给每一个人,有C(a[i]+n-1,m-1)种方案,而总方案数就是每种
物品方案数的乘积
然后,根据容斥原理,ans = 至少0人没分到特产 - 至少1人没分到特产 + ... - C(m,m) * 没有一人分到
特产
【代码】
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2010
const long long P = 1000000007 ;
int i,n,m;
long long a[MAXN],fac[MAXN],inv[MAXN];
long long ans;
inline long long power(long long a,long long n)
{
long long ans = 1,b = a;
while (n > 0)
{
if (n & 1) ans = (ans * b) % P;
b = (b * b) % P;
n >>= 1;
}
return ans;
}
inline void init()
{
int i;
fac[0] = 1;
for (i = 1; i < MAXN; i++) fac[i] = fac[i-1] * i % P;
inv[MAXN-1] = power(fac[MAXN-1],P-2);
for (i = MAXN - 2; i >= 1; i--) inv[i] = inv[i+1] * (i + 1) % P;
inv[0] = 1;
}
inline long long C(int n,int m)
{
return fac[n] * inv[n-m] % P * inv[m] % P;
}
inline long long calc(int x)
{
int i;
long long ans = 1;
for (i = 1; i <= m; i++) ans = (ans * C(a[i]+n-x-1,n-x-1)) % P;
return ans;
}
int main()
{
init();
scanf("%d%d",&n,&m);
for (i = 1; i <= m; i++) scanf("%d",&a[i]);
for (i = 0; i <= n; i++)
{
if (i % 2 == 0) ans = (ans + C(n,i) * calc(i)) % P;
else ans = (ans - (C(n,i) * calc(i) % P) + P) % P;
}
printf("%lld\n",ans);
return 0;
}