题意:
有K中颜色去涂球,第i中颜色要涂ci个球,不能位置的球颜色相同是有区别的,涂完第i种球的时候前i-1种球必须先涂完,问总共有多少种涂法
分析:
一开始想按涂球的数量递推,然后发现是不行的,复杂度太大
这题怎么想呢,按已涂的颜色数量来递推。
怎么想呢?
假设我们已经涂了前i-1种颜色的球,并且种类为dp[i-1],并且前i-1中颜色的球的总数是presum,这个时候我们要涂第i中颜色的ci个球,这就相当于把ci-1个球插入到presum个球中间去,并且把最后一个放到最后,那么dp[i] = dp[i-1] * C(ci-1+presum,ci-1)
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const long long MOD = 1000000007;
long long f[1100], fe[1100];
long long dp[1100];
int K, num[1100];
long long getf( long long x ){
long long ans = 1, temp = MOD - 2;
while( temp ){
if( temp & 1 ){
ans = ans * x % MOD;
}
x = x * x % MOD;
temp /= 2;
}
return ans;
}
void init(){
f[0] = f[1] = 1;
fe[0] = fe[1] = 1;
for( int i = 2; i <= 1000; i++ ){
f[i] = f[i-1] * i % MOD;
fe[i] = fe[i-1] * getf( i ) % MOD;
}
}
int main(){
init();
scanf( "%d", &K );
for( int i = 0; i < K; i++ ){
scanf( "%d", &num[i] );
}
dp[0] = 1;
int presum = num[0];
for( int i = 1; i < K; i++ ){
dp[i] = dp[i-1] * f[presum + num[i]-1] % MOD * fe[num[i]-1] % MOD * fe[presum] % MOD;
presum += num[i];
}
printf( "%I64d\n", dp[K-1] );
return 0;
}