题目意思:
给定若干字母和它们相应的个数,计算可以组成多少个不同的字符
http://acm.hdu.edu.cn/showproblem.php?pid=1261
题目分析:
组合公式的直接应用,s!/(ai!) s:字符总数 ai:第i个字符的个数,用数组实现高精度的组合公式
不要直接求是S!的阶乘,那样会超时,需要上下同时求,约去最大公约数,在将剩下的值模拟相乘
AC代码:
/**
*s!/(ai!) s:字符总数 ai:第i个字符的个数
*(高精度)
*/
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int cmp(int a,int b){
return a>b;
}
int gcd(int a,int b){
if(b==0) return a;
else return gcd(b,a%b);
}
int main()
{
int n,a[30],sum[501];//sun储存结果
int s2[400],b[27][15];//存储i便于计算
while(cin>>n&&n){
int i,j,k;
int s=0;
for(i=1;i<=n;i++){
cin>>a[i];
s+=a[i];
}
for(i=1;i<=s;i++){//记录所有个数
s2[i]=i;
}
for(k=1;k<=n;k++){
for(j=2;j<=a[k];j++){
int m=j;
while(m>1){
for(i=1;i<=s;i++){
int m1=gcd(s2[i],m);
m=m/m1;
s2[i]=s2[i]/m1;
}
}
}
}
memset(sum,0,sizeof(sum));
//cout<<m<<endl;
sum[0]=1;
for(i=1;i<=s;i++){//模拟相乘没有约去的值
//cout<<s2[i]<<" ";
int flag=0;
if(s2[i]!=1) for(j=0;j<=500;j++){
int ss=sum[j]*s2[i]+flag;
sum[j]=ss%10;
flag=ss/10;
}
//s1*=s2[i];
}
for(i=500;!sum[i];i--);
//cout<<i<<endl;
for(j=i;j>=0;j--){
cout<<sum[j];
}
cout<<endl;
}
return 0;
}