bzoj2729: [HNOI2012]排队

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
 
题解:
组合数学+高精度。。。。。
先将男生排序
分两种情况
1.将两个老师看成一个人,放在男生里面,这时两个老师之间必须放一个女生,剩下的女生放再其他可以放的位子
2.两个老师分别用男生隔开,在把女生放进去
ans=n!(2(n+1)*A(n+2,m-1)+n*(n+1)*A(n+3,m))
=(n+1)!A(n+2,m-1)(n2+3n+2m)
code:
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #define MAXN 3000
  7 #define maxnum 10000
  8 using namespace std;
  9 char ch;
 10 bool ok;
 11 void read(int &x){
 12     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
 13     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
 14     if (ok) x=-x;
 15 }
 16 struct bignum{
 17     int len,v[MAXN];
 18     bignum(){memset(v,0,sizeof(v)),len=1;}
 19     bignum operator=(const char* num){
 20         memset(v,0,sizeof(v));
 21         len=((strlen(num)-1)>>2)+1;
 22         int j=1,k=0;
 23         for (int i=strlen(num)-1;i>=0;i--){
 24             if (j==maxnum) j=1,k++;
 25             v[k]+=(num[i]-'0')*j;
 26             j*=10;
 27         }
 28     }
 29     bignum operator=(const int num){
 30         char a[MAXN<<2];
 31         sprintf(a,"%d",num);
 32         *this=a;
 33         return *this;
 34     }
 35     bignum (int num){*this=num;}
 36     bignum (const char* num){*this=num;}
 37     bignum operator+(const bignum &a){
 38         bignum c;
 39         c.len=max(len,a.len);
 40         for (int i=0;i<c.len;i++){
 41             c.v[i]+=v[i]+a.v[i];
 42             if (c.v[i]>=maxnum) c.v[i+1]+=(c.v[i]/maxnum),c.v[i]%=maxnum;    
 43         }
 44         while (c.v[c.len]) c.len++;
 45         return c;
 46     }
 47     bignum operator-(const bignum b){
 48         bignum a,c;
 49         a=*this;
 50         c.len=len;
 51         for (int i=0;i<len;i++){
 52             if (a.v[i]<b.v[i]) a.v[i+1]--,a.v[i]+=maxnum;
 53             c.v[i]=a.v[i]-b.v[i];
 54         }    
 55         while (c.len>1&&!(c.v[c.len-1])) c.len--;
 56         return c;
 57     }
 58     bignum operator*(const bignum &a){
 59         bignum c;
 60         c.len=len+a.len;
 61         for (int i=0;i<len;i++)
 62             for (int j=0;j<a.len;j++){
 63                 c.v[i+j]+=v[i]*a.v[j];
 64                 if (c.v[i+j]>=maxnum) c.v[i+j+1]+=(c.v[i+j]/maxnum),c.v[i+j]%=maxnum;    
 65             }
 66         while (c.len>1&&!(c.v[c.len-1])) c.len--;
 67         return c;
 68     }
 69     bignum operator*(const int &a){
 70         bignum c=a;
 71         return *this*c;    
 72     }
 73     /*
 74     inline bignum operator*(const int &a){
 75         bignum c;
 76         c.len=len;
 77         for (int i=0;i<len;i++){
 78             c.v[i]+=v[i]*a;
 79             if (c.v[i]>=maxnum) c.v[i+1]=(c.v[i]/maxnum),c.v[i]%=maxnum;    
 80         }    
 81         if (c.v[c.len]) c.len++;
 82         return c;
 83     }
 84     */
 85     bignum operator/(const int &b){
 86         bignum c;
 87         int x=0;
 88         for (int i=len-1;i>=0;i--){
 89             c.v[i]=(x*maxnum+v[i])/b;
 90             x=(x*maxnum+v[i])%b;
 91         }
 92         c.len=len;
 93         while (c.len>1&&!(c.v[c.len-1])) c.len--;
 94         return c;
 95     }
 96     bignum operator+=(const bignum &a){*this=*this+a;return *this;}
 97     bignum operator-=(const bignum &a){*this=*this-a;return *this;}
 98     bignum operator*=(const bignum &a){*this=*this*a;return *this;}
 99     bignum operator/=(const int &a){*this=*this/a;return *this;}
100     bool operator < (const bignum &x)const{
101         if (len!=x.len) return len<x.len;
102         for (int i=len-1;i>=0;i--)
103             if (v[i]!=x.v[i]) return v[i]<x.v[i];
104         return false;
105     }
106     bool operator > (const bignum &x)const{return x<*this;}
107     bool operator <=(const bignum &x)const{return !(x<*this);}
108     bool operator >=(const bignum &x)const{return !(*this<x);}
109     bool operator ==(const bignum &x)const{return !(x<*this||*this<x);}
110     bool operator !=(const bignum &x)const{return x<*this||*this<x;}
111 }ans,tmp;    
112 void write(bignum x){
113     printf("%d",x.v[x.len-1]);
114     for (int i=x.len-2;i>=0;i--) printf("%0*d",4,x.v[i]);    
115 }
116 int n,m;
117 int main(){
118     read(n),read(m);
119     ans=n*n+3*n+2*m;
120     for (int i=1;i<=n+1;i++) ans=ans*i;
121     for (int i=n-m+4;i<=n+2;i++) ans=ans*i;
122     write(ans);
123     return 0;
124 }

 

posted @ 2016-01-03 11:44  chenyushuo  阅读(185)  评论(0编辑  收藏  举报