51nod 1453抽彩球
收藏
关注
一个袋子中有n个彩球,他们用k种不同的颜色染色。颜色被从1到k编号。同一种颜色的球看成是一样的。现在从袋中一个一个的拿出球来,直到拿完所有的球。对于所有颜色为i (1<=i<=k-1)的球,他的最后一个球总是在编号比他大的球拿完之前拿完,问这样情况有多少种。
样例解释:这个样例中有2个1号颜色的球,2个2号颜色的球,1个3号颜色的球。三种方案是:
1 2 1 2 3
1 1 2 2 3
2 1 1 2 3
Input
单组测试数据。 第一行给出一个整数k(1 ≤ k ≤ 1000),表示球的种类。 接下来k行,每行一个整数ci,表示第i种颜色的球有ci个(1 ≤ ci ≤ 1000)。 球的总数目不超过1000。
Output
输出总数对1,000,000,007的模即可。
Input示例
3 2 2 1
Output示例
3
思路:当我上一个的确定后,代表我当前的这个的最后一个位置确定了
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1100; 5 const ll MOD=1e9+7; 6 7 ll F[N], Finv[N], inv[N]; 8 void init(){ 9 inv[1] = 1; 10 for(int i = 2; i < N; i ++){ 11 inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; 12 } 13 F[0] = Finv[0] = 1; 14 for(int i = 1; i < N; i ++){ 15 F[i] = F[i-1] * 1ll * i % MOD; 16 Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD; 17 } 18 } 19 ll comb(ll n, ll m){//comb(n, m)就是C(n, m) 20 if(m < 0 || m > n) return 0; 21 return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD; 22 } 23 int a[N]; 24 int main(){ 25 int k; 26 init(); 27 cin>>k; 28 int sum=0; 29 for(int i=1;i<=k;i++) { 30 scanf("%d",&a[i]); 31 sum+=a[i]; 32 } 33 ll ss=1; 34 for(int i=k;i>=1;i--){ 35 ss=ss*(comb(sum-1,a[i]-1))%MOD; 36 37 sum-=a[i]; 38 } 39 cout<<ss<<endl; 40 }