http://en.wikipedia.org/wiki/Young_tableau
看了上面这篇有关钩子公式的论文后,这题就变水题了,记得用__int64 即可。如果不想看英文的话可以看黑书,在组合数学P93那部分有相关内容。此题还可以用dp来解,其实很多组合数学题都是如此,可以去看看foverlin神的blog,那里有很详细的解释。
以下是代码:
- #include<cstdio>
#include<iostream>
using namespace std;
const int N=20;
const int M=200;
__int64 c[N],sum[M];
__int64 n; - __int64 gcd(__int64 a,__int64 b)
{
return a%b==0?b:gcd(b,a%b);
} - int main()
{
while(scanf("%I64d",&n),n)
{
__int64 i,j,k;
__int64 cnt;
__int64 x=1,y=1,ans;
for(i=1;i<=n;i++)
scanf("%I64d",&c[i]);
cnt=0;
for(i=1;i<=155;i++)
sum[i]=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=c[i];j++)
{
cnt++;
for(k=i+1;k<=n;k++)
{
if(c[k]>=j) sum[cnt]++;
else break;
}
sum[cnt]+=c[i]-j+1;
}
}
for(i=1;i<=cnt;i++)
{
x*=i;
y*=sum[i];
__int64 tmp=gcd(x,y);
if(tmp!=1)
{
x/=tmp;
y/=tmp;
}
}
ans=x/y;
printf("%I64d/n",ans);
}
return 0;
}