Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1362 Solved: 632
[Submit][Status][Discuss]
Description
某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)
Input
只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述。
对于 30%的数据 n≤100,m≤100
对于 100%的数据 n≤2000,m≤2000
Output
输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数。注意答案可能很大。
Sample Input
1 1
Sample Output
12
HINT
Source
day1
排列组合
公式:
A(n,n)(A(n+1,2)*A(n+3,m)+A(2,2)(n+1)*A(n+2,m-1)*m)
1.考虑男生顺序 n!
2.考虑将老师和女生分别加入队中,老师A(n+1,2),女生A(n+3,m);
3.考虑两个老师之间有女生 老师排列A(2,2),(n+1)(老师,女生,老师),剩余女生排列A(n+2,m-1),插入老师之间的女生 m
综上所述A(n,n)* (A(n+1,2) A(n+3,m)+A(2,2)(n+1)* A(n+2,m-1)*m)
提取公因式(n* (n+3)+m* 2)* A(n,n)*A(n+2,m-2)
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 10005
#define Mod 100000000
struct Big{
int l;
long long num[N];
}a;
int n,m;
void mul(const int &x){
for(int i=1;i<=a.l;i++)
a.num[i]*=x;
for(int i=1;i<=a.l;i++)
if(a.num[i]>9) a.num[i+1]+=a.num[i]/Mod,a.num[i]%=Mod;
while(a.num[a.l+1]) a.l++;
}
void print(){
printf("%d",a.num[a.l]);
for(int i=a.l-1;i>=1;i--) printf("%08d",a.num[i]);
putchar('\n');
}
void work(){
int mid=n*(n+3)+m*2,l;
a.l=1;a.num[1]=mid;
for(int i=1;i<=n+1;i++) mul(i);
for(int i=n-m+4;i<=n+2;i++) mul(i);
print();
}
int main(){
scanf("%d%d",&n,&m);
if(n+3<m) cout<<"0"<<endl;
else work();
return 0;
}
// else print(A(n,n)*(A(n+1,2)*A(n+3,m)+A(2,2)*(n+1)*A(n+2,m-1)*m));