组合数学起步-排队[HNOI2012][BZOJ2729]

<题面>

这个题十分基础

写这个博客给自己看的呵呵

遇到这个题,一看就是组合数学,

so,开始推公式,

刚开始想的是,先排男生,再排女生,最后排老师

推了一会,呃呃呃,情况复杂,考虑的好像有点多。//蒟蒻心态

然后换了一个思路,

先排男生,再排老师,最后排女生

想了下,就决定用减法。


先把老师和男生混好,然后把女生插空

这样就会有一种非法情况,老师相连,而且只有一种

这样就可以把两个老师绑成一个整体,再按上述操作进行

最后蒻蒻的说:我调这个题主要在高精度上,苦笑

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #define N 50000
  5 using namespace std;
  6 struct Hyper_long{
  7     int *a;
  8     Hyper_long(int k){
  9         a=new int[k];
 10         for(int i=0;i<k;i++)a[i]=0;
 11     }    
 12     void in(char *st){
 13         a[0]=strlen(st);
 14         for(int i=0,j=a[0];i<a[0];i++,j--){
 15             a[j]=st[i]-'0';
 16         }
 17     }
 18     void readin(){
 19         char st[N];
 20         scanf("%s",st);
 21         in(st);
 22     }
 23     void out(){
 24         if(a[0]==0)putchar('0');
 25         for(int i=a[0];i>=1;i--)putchar(a[i]+'0');
 26         puts("");
 27     }
 28     void set_length(int len){
 29         a[0]=len;
 30     }
 31     int length(){
 32         return a[0];
 33     }
 34 };
 35 Hyper_long operator + (Hyper_long x,Hyper_long y){
 36     Hyper_long m(N);
 37     int i=1,r=0;
 38     while(i<=x.length() || i<=x.length() || r!=0){
 39         m.a[i]=x.a[i]+y.a[i]+r;
 40         r=m.a[i]/10;
 41         m.a[i]%=10;
 42     }
 43     m.set_length(i);
 44     return m;
 45 }
 46 void operator *= (Hyper_long &x,int y){
 47     long long r=0;
 48     for(int i=1;i<=x.length();i++){
 49         x.a[i]=x.a[i]*y+r;
 50         r=x.a[i]/10;
 51         x.a[i]%=10;
 52     }
 53     while(r!=0){
 54         x.a[0]++;
 55         x.a[x.a[0]]=r;
 56         r=x.a[x.a[0]]/10;
 57         x.a[x.a[0]]%=10;
 58     }
 59     return ;
 60 }
 61 Hyper_long JC(int x){
 62     Hyper_long k(N);
 63     k.a[0]=1,k.a[1]=1;
 64     for(int i=1;i<=x;i++){
 65         k*=i;
 66     }    
 67     return k;
 68 }
 69 Hyper_long operator - (Hyper_long x,Hyper_long y){
 70     Hyper_long k(N);
 71     int len=max(x.length(),y.length());
 72     for(int i=1;i<=len;i++){
 73         k.a[i]=x.a[i]-y.a[i];
 74         if(k.a[i]<0){
 75             x.a[i+1]--;
 76             k.a[i]+=10;
 77         }
 78     }
 79     while(1){
 80         if(k.a[len]!=0 || len==0) break;
 81         len--;
 82     }
 83     k.set_length(len);
 84     return k;
 85 }
 86 Hyper_long a(N),b(N),c(N);
 87 int m,n;
 88 int main(){
 89     a.a[0]=a.a[1]=1;
 90     b.a[0]=b.a[1]=1;
 91     scanf("%d%d",&n,&m);
 92     for(int i=1;i<=n+2;i++){//先把男生和老师混在一起 
 93         a*=i;
 94     }
 95     for(int i=n+3;i>=n+3-m+1;i--){//把女生插进去 
 96         a*=i;
 97     }
 98     b*=2;//把两个老师绑在一起 
 99     for(int i=1;i<=n+1;i++){//和男生混好
100         b*=i;
101     }
102     for(int i=n+2;i>=n+2-m+1;i--){//把女生插进去 
103         b*=i;
104     }
105     c=a-b;
106     c.out();//输出 
107 }
Code

猜你喜欢

转载自www.cnblogs.com/kalginamiemeng/p/11109381.html