题意:
给你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;
}