传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4248
题目大意:
有n种颜色的求各a[i]个,颜色相同的无任何区别,求拿出分别拿出1个,2个,,,,n个的排列方案数。
解题思路:
dp[i][j]–用前i种放j个球的方案数
dp[i][j]+=dp[i-1][j-k]*C[j][k],k表示插入k个,利用插空法就是C[j][k]。
Code:
/* W w w mm mm 222222222 7777777777777 */
/* W w w w m m m m 222 22 7777 */
/* w w w w m m m m 22 777 */
/* w w w w m m m m 22 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* w w w w m m m m 222 77 */
/* ww ww m mm m 222222222222222 77 */
//#pragma comment(linker, "/STACK:102400000,102400000")
//C++
//int size = 256 << 20; // 256MB
//char *p = (char*)malloc(size) + size;
//__asm__("movl %0, %%esp\n" :: "r"(p));
//G++
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<ctime>
#include<deque>
#include<cmath>
#include<vector>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#define REP(i,s,t) for(int i=(s);i<=(t);i++)
#define REP2(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned long ul;
const int N=105;
const int MOD=1000000007;
int T;
int a[N];
int C[N*N][N];
int dp[N][N*N];
int n;
void fuck()
{
memset(C,0,sizeof(C));
C[0][0]=1;
REP(i,1,10001)
{
C[i][0]=1;
int _min=min(i,101);
REP(j,1,_min)
{
C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;
}
}
}
void debug()
{
REP(i,1,5)
{
REP(j,0,i)
{
printf("C[%d][%d]=%d\n",i,j,C[i][j]);
}
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("test.in","r",stdin);
#endif
int ca=1;
fuck();
//debug();
while(~scanf("%d",&n))
{
REP(i,1,n)
{
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
REP(i,0,a[1])
{
dp[1][i]=1;
}
int sum=a[1];
REP(i,2,n)
{
sum+=a[i];
REP(j,0,sum)
{
int _min=min(j,a[i]);
REP(k,0,_min)
{
dp[i][j]=(int)(((ll)dp[i-1][j-k]*C[j][k]+dp[i][j])%MOD);
}
}
}
int ans=0;
REP(i,1,sum)
{
ans=(int)(((ll)ans+dp[n][i])%MOD);
}
printf("Case %d: %d\n",ca++,ans);
}
return 0;
}