HDU

来源:互联网 发布:农村创业软件 编辑:程序博客网 时间:2024/06/07 10:52

题目链接


题意:

一个A和两个B一共可以组成三种字符串:"ABB","BAB","BBA". ,给定若干字母和它们相应的个数,

计算一共可以组成多少个不同的字符串.


思路:

  这个算是一个水题了,直接套多重集合排列的公式,这个公式也只适用于当r==n的情况.

公式为:

n!/(n1!*n2!*n3!....nk!)    n为所有字母的和.

   上述可以理解成,n个位置,第一个位置n个选法,第2个(n-1)个,.....到最后就是n!个选法,对于每个集合ni,进行去重,就得到了上述的公式.


但是这个题,每个字母最多12,直接算存不下,只能用大数来模拟了.

#include<bits/stdc++.h>#define Ri(a) scanf("%d", &a)#define Rl(a) scanf("%lld", &a)#define Rf(a) scanf("%lf", &a)#define Rs(a) scanf("%s", a)#define Pi(a) printf("%d\n", (a))#define Pf(a) printf("%lf\n", (a))#define Pl(a) printf("%lld\n", (a))#define Ps(a) printf("%s\n", (a))#define W(a) while(a--)#define CLR(a, b) memset(a, (b), sizeof(a))#define MOD 1000000007#define inf 0x3f3f3f3f#define exp 0.00000001#define  pii  pair<int, int>#define  mp   make_pair#define  pb   push_backusing namespace std;typedef long long ll;const int maxn=1e5+10;const int base=100000;int num[1111];int n,a[30];int main(){while(~Ri(n)){if(n==0)break;int s=0;for(int i=1;i<=n;i++){Ri(a[i]);s+=a[i];}CLR(num,0);num[0]=1;int car=0;int len=1;for(int i=2;i<=s;i++){car=0;for(int j=0;j<len;j++){num[j]=num[j]*i+car;if(num[j]>=base){car=num[j]/base;num[j]%=base;}elsecar=0;}if(car!=0)num[len++]=car;}int res=0;//int w;for(int i=1;i<=n;i++){for(int j=2;j<=a[i];j++){for(int k=len-1;k>=0;k--){res=num[k]+res*base;num[k]=res/j;res=res%j;}}}int item=-1;int flag=0;for(int i=1000;i>=0;i--){if(num[i]!=0){item=i;break;} }  for(int i=item;i>=0;i--) { if(!flag) printf("%d",num[i]),flag=1; else printf("%05d",num[i]); } puts("");} return 0;}


 

原创粉丝点击