CodeForces #554 C Kyoya and Colored Balls

C. Kyoya and Colored Balls
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Kyoya Ootori has a bag with n colored balls that are colored with k different colors. The colors are labeled from 1 to k. Balls of the same color are indistinguishable. He draws balls from the bag one by one until the bag is empty. He noticed that he drew the last ball of color ibefore drawing the last ball of color i + 1 for all i from 1 to k - 1. Now he wonders how many different ways this can happen.

Input

The first line of input will have one integer k (1 ≤ k ≤ 1000) the number of colors.

Then, k lines will follow. The i-th line will contain ci, the number of balls of the i-th color (1 ≤ ci ≤ 1000).

The total number of balls doesn't exceed 1000.

Output

A single integer, the number of ways that Kyoya can draw the balls from the bag as described in the statement, modulo 1 000 000 007.

Examples
input
3
2
2
1
output
3
input
4
1
2
3
4
output
1680
Note

In the first sample, we have 2 balls of color 1, 2 balls of color 2, and 1 ball of color 3. The three ways for Kyoya are:

1 2 1 2 3
1 1 2 2 3
2 1 1 2 3


这是codeforces上的一道题,在一次训练赛里出现,赛时没有思路,没有做出来。

题意:

有很多球,颜色不同,其他无差别,把它按一定顺序排列,使得颜色编号小的球比颜色编号大的球先取完,是一道排列组合题目。

思路:

既然要颜色从小到大结束,那么假如我们有三种颜色 1,2,3; 分别有 2,2,1个;

我们从2号开始,最后的那个2号,它前面还有2个1号和一个2号,所以是C(3,1)  (ps:前面共有三个球,2个一号一个2号,所以只要在三个位置中找一个给2号) 然后接下来是3号球,它前面有2个2号和2个一号 所以是C(4,0) (ps:前面有4个球,还剩下0个3号球,所以不需要排)   情况遍历结束 answer = C(3,1) * C(4,0) = 3;

我先把 C(n,m) 运算的表打了出来,然后后面再遍历各种球。

下面是AC代码:


#include<stdio.h>      
#define maxn 1000000007  
int a[1600];  
__int64  c[1050][1060];  	//存C(n,m)的表 
__int64  ans;  
  
int main(){  
    int n,m,i,j,total;  
    for(i = 1;i <= 1000;i++)
		c[i][0] = 1;  
    for(i = 1;i <= 1000;i++){  
        for(j = 1;j <= i;j++){  
            if(i == j)
				c[i][j] = 1;  
            else if(i > j)  
            c[i][j] = (c[i-1][j] + c[i-1][j-1]) % maxn;  
        }  
    } 
    
    //上面的代码是打表 C(n,m) 的运算结果 
      
    while(scanf("%d",&n)!=EOF){  
        for(i = 1;i <= n;i++){  
            scanf("%d",&a[i]);  
        }  
        total = a[1];
		ans = 1;  
        for(i = 2;i <= n;i++){  // 因为 1号球总是最先取完,所以我们从2号球开始排列组合 
            total += a[i];   
            ans = (ans * c[total - 1][a[i] - 1]) % maxn;    //把各个球的排列组合乘起来 
        }  
        printf("%I64d\n",ans);  
    }  
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值