Codeforces Round #309 (Div. 1) A Kyoya and Colored Balls

题意:

给你K种颜色的球,第i种颜色的球有Si个 (K<= 1000 sum(Si)<= 1000)

将所有的球排列,排列时最后一个第i种颜色的球的后面必须是第i+1种颜色的球

求有多少种排列组合


方法:

设sum为球的总数,首先可以想到最后一个球肯定是第K种颜色的球(因为其他颜色的球在最后一个就是该颜色的最后一个球,明显是不合理的),然后剩下K颜色的Sk-1个球可以随意摆,

即C(sum-1,Sk-1)

然后我们可以知道剩下的空格中的最后一个球肯定是第K-1颜色的球(原因同上),所以我们剩下k-1颜色的S(k-1)-1个球可以在剩下的sum-Sk-1的空格中随意摆,即C(sum-Sk-1,S(k-1)-1)

依次类推,可以从第k种颜色一直推到第1种颜色的可能,把每一种的可能性相乘就是结果


PS: 看到别人的解题报告,发现其实填了k种颜色的Sk个球之后,把这Sk个空格去掉,变成连续的sum-Sk个空格 容易理解多了


代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#define LL long long
#define MOD 1000000007

LL A[1111];
LL C[1010][1010];

int main()
{
    C[0][0]= 1;
    for(int i= 1; i<= 1000; i++)
        C[i][0]= C[i][i]= 1;
    for(int i= 2; i<= 1000; i++)
        for(int j= 1; j<= i-1; j++)
            C[i][j]= (C[i-1][j]+ C[i-1][j-1])% MOD; 
    LL k;
    while(scanf("%lld",&k)!=EOF)
    {
        LL ans= 1;
        LL sum= 0;
        for(int i= 1; i<= k; i++)
        {
            scanf("%lld",&A[i]);
            sum+= A[i];
        }
        for(int i= k; i>= 1; i--)
        {
            ans= (ans* C[sum-1][A[i]-1])%MOD;
            sum-= A[i];
        }
        printf("%lld\n",ans);                    
    }
    return 0;
} 


你可能感兴趣的:(Codeforces Round #309 (Div. 1) A Kyoya and Colored Balls)