题意:n种颜色的小球,第i个颜色的球有c[i]个.
规则:颜色i的最后一个球必须在颜色i+1最后一个的前面.[i=1..k-1].(也就是颜色i+1不能比颜色i先放完)
n,c[i]<=1000.总的球个数<=1000,问有多少种合法的放法?
假如已经放好前i种颜色,现在插入第i种颜色.
显然最后一位置放第i种颜色,然后剩下c[i]-1个元素插入前面m=pre[i-1]+1个位置中即可.
有重复选择的组合x1+x2+...xm=c[i]-1
规则:颜色i的最后一个球必须在颜色i+1最后一个的前面.[i=1..k-1].(也就是颜色i+1不能比颜色i先放完)
n,c[i]<=1000.总的球个数<=1000,问有多少种合法的放法?
假如已经放好前i种颜色,现在插入第i种颜色.
显然最后一位置放第i种颜色,然后剩下c[i]-1个元素插入前面m=pre[i-1]+1个位置中即可.
有重复选择的组合x1+x2+...xm=c[i]-1
令yi=xi+1 -> y1+y2+..ym=c[i]-1+m=tot.然后从tot-1个间隔中选m-1个:C(tot-1,m-1).
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,mod=1e9+7;
int n,K,c[N],pre[N];
ll f[N];
ll powmod(ll x,ll n)
{
ll s=1;
while(n)
{
if(n&1)
s=(s*x)%mod;
n>>=1;
x=(x*x)%mod;
}
return s;
}
ll C(int n,int m)
{
ll a=f[n],b=(f[n-m]*f[m])%mod;
return (a*powmod(b,mod-2))%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
f[0]=1;
for(int i=1;i<N;i++)
f[i]=(f[i-1]*i)%mod;
cin>>K;
for(int i=1;i<=K;i++)
cin>>c[i],pre[i]=pre[i-1]+c[i];
ll res=1;
for(int i=2;i<=K;i++)
{
//x1+x2+..xm=c[i]-1
//y1+y2...ym=c[i]-1+m
int m=pre[i-1]+1;
int tot=c[i]-1+m-1,r=m-1;
res=(res*C(tot,r))%mod;
}
cout<<res<<'\n';
return 0;
}