[2017-3-10]BNUZ套题比赛div2 C

来源:互联网 发布:sql insert多条记录 编辑:程序博客网 时间:2024/05/01 08:27

CodeForces - 554C

http://codeforces.com/problemset/problem/554/C


题意:

有k种颜色,每种颜色对应a[i]个球,球的总数不超过1000
要求第i种颜色的最后一个球,其后面接着的必须是第i+1种颜色的球
问一共有多少种排法

思路:

首先我们容易想到我们必须要确定每种颜色最后一个球的放法
所有对于最后一种颜色,假设这种颜色有b个球,而总球数为a
那么必然有一个球是放在最后一个位置的,那么剩下的球就是z=C(b-1,a-1)种方法
那么对于倒数第二种球,假设有x个,此时总球数位y=a-b
那么之前已经有z种方法了,而对于每一种放法,此时倒数第二种颜色拿出一个作为最后一个球的话,它对于每种放法必然只有一个固定方法,位置是最后一个没有放球的位置,这样既保证放法符合要求,而剩下的球就有C(x-1,y-1)种放法
然后相乘得到最后一种颜色与最后第二种颜色的方法,以此类推。。

代码:

#include<bits/stdc++.h> #define N 2010#define M 1000000007using namespace std;long long a[1010];long long C[N][N];void GetC(){    C[0][0] = C[1][0] = C[1][1] = 1;    for(int i = 2;i < N;i++){        C[i][0] = 1;        C[i][i] = 1;        for(int j = 1;j < i;j++){            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % M;        }    }}int main() {    int n,i,j;    GetC();    while(~scanf("%d",&n)){        long long sum = 0;        memset(a,0,sizeof(a));        for(i = 1;i <= n;i++){            scanf("%lld",&a[i]);            sum += a[i];        }        long long num = 1;        for(i = n;i >= 2;i--){            num = (num % M * C[sum - 1][a[i] - 1]) % M;            sum -= a[i];        }        printf("%lld\n",num % M);    }    return 0;}
0 0