[BZOJ2729]排队
数学知识
排列 A(n,m)从n个元素中选出m个的不同的排列数 A(n,m)=n!/(n-m)!
组合 C(n,m)从n个元素中选出m个的不同的方案数 C(n,m)=n!/(m!*(n-m)!)
题目描述
输入格式
输出格式
样例
题解
1.首先,很容易想到
所有男生全排列,然后老师和女生分别插空,即A(n,n)*A(n+1,2)*A(n+3,m)
2.但是手模样例,发现少情况了,细细一想,
老师中间只有女生的情况没有考虑
男生全排列,然后女生选一个,接着老师前后排,两个老师加一个女生捆绑后,在男生中插空,最后别忘了把剩下的m-1个女生插到n+1+1个空里
即 A(n,n)*A(m,1)*A(2,2)*A(n+1,1)*A(n+2,m-1)
所以根据分步加法原理
两种情况相加,并化简
得 n!*(n+2)!*(n+1)(n^2+3*n+2*m)/(n-m+3)!
再用高精乘低精即可很容易实现
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 int n,m,len=1,a[100000001]; 6 7 void mul(int x) 8 { 9 int k=0; 10 for(int i=1;i<=len;i++) 11 { 12 a[i]=a[i]*x+k; 13 k=a[i]/10; 14 a[i]%=10; 15 if(k>0&&i==len) len++; 16 } 17 } 18 signed main() 19 { 20 scanf("%d%d",&n,&m); 21 a[1]=1;len=1; 22 for(int i=1;i<=n+1;i++) 23 mul(i); 24 for(int i=n-m+4;i<=n+2;i++) 25 mul(i); 26 mul(n*n+n*3+m*2); 27 for(int i=len;i>=1;i--) 28 printf("%d",a[i]); 29 }
愿你在迷茫时,记起自己的珍贵。