一个袋子中有n个彩球,他们用k种不同的颜色染色。颜色被从1到k编号。同一种颜色的球看成是一样的。现在从袋中一个一个的拿出球来,直到拿完所有的球。对于所有颜色为i (1<=i<=k-1)的球,他的最后一个球总是在编号比他大的球拿完之前拿完,问这样情况有多少种。
样例解释:这个样例中有2个1号颜色的球,2个2号颜色的球,1个3号颜色的球。三种方案是:
1 2 1 2 3
1 1 2 2 3
2 1 1 2 3
Input
单组测试数据。 第一行给出一个整数k(1 ≤ k ≤ 1000),表示球的种类。 接下来k行,每行一个整数ci,表示第i种颜色的球有ci个(1 ≤ ci ≤ 1000)。 球的总数目不超过1000。
Output
输出总数对1,000,000,007的模即可。
Input示例
3 2 2 1
Output示例
3
System Message
(题目提供者)
C++的运行时限为:1000 ms ,空间限制为:131072 KB
示例及语言说明请按这里
允许其他 AC 的用户查看此代码,分享代码才能查看别人的代码并有机会获得勋章
运用了组合数学插空法的知识
https://baike.baidu.com/item/%E6%8F%92%E7%A9%BA%E6%B3%95/4862293?fr=aladdin
对于每种球,只有一个要求,那就是每种球最后一个是固定的,只其余的求可以随便放。
所以我们倒着来。算计算一共有多少球,sum个。
最后一种颜色的最后一个球肯定放在最后
我们只需要在前sum-1个空位随便选择a[i]个位置把这些球放进去即可。 C(sum-1,a[i]);
之后让sum-=a[i]。代表着空位少了a[i]个了。
同理,继续对于下一个球,最后一个球固定,放在sum位置,从前sum-1个位置找a[i]个放进入 C(sum-1,a[i])。
利用逆原来处理组合数即可。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n;
int a[1100];
long long fac[1100];
const int MOD=1000000007;
//
//求组合数
long long ppow(long long x, long long y)
{
long long c = 1;
while (y)
{
if (y & 1)
{
c = c * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return c;
}
long long C(long long m, long long i)
{
return ((fac[m] % MOD) * (ppow((fac[i] * fac[m-i]) % MOD, MOD - 2) % MOD)) % MOD;
}
void init()
{
fac[0] = 1;
for(int i = 1; i < 1000; i++)
{
fac[i] = (fac[i - 1] * i) % MOD;
}
}
///
int main()
{
init();
long long ans = 1,sum = 0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
for(int i=n-1;i>=0;i--)
{
ans=ans*C(sum-1,a[i]-1);
ans=ans%MOD;
sum-=a[i];
}
cout<<ans<<endl;
}
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
int n;
int a[1100];
long long fac[1100];
const int MOD=1000000007;
//
//求组合数
long long ppow(long long x, long long y)
{
long long c = 1;
while (y)
{
if (y & 1)
{
c = c * x % MOD;
}
y >>= 1;
x = x * x % MOD;
}
return c;
}
long long C(long long m, long long i)
{
return ((fac[m] % MOD) * (ppow((fac[i] * fac[m-i]) % MOD, MOD - 2) % MOD)) % MOD;
}
void init()
{
fac[0] = 1;
for(int i = 1; i < 1000; i++)
{
fac[i] = (fac[i - 1] * i) % MOD;
}
}
///
int main()
{
init();
long long ans = 1,sum = 0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
for(int i=n-1;i>=0;i--)
{
ans=ans*C(sum-1,a[i]-1);
ans=ans%MOD;
sum-=a[i];
}
cout<<ans<<endl;
}