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

<题面>

这个题十分基础

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

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

so,开始推公式,

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

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

然后换了一个思路,

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

想了下,就决定用减法。


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

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

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

就会有一个式子:

$A inom{n+2}{n+2} imes A inom{m}{n+3} -A inom{2}{2} imes A inom{n+1}{n+1} imes Ainom{m}{n+2}$

还是可以懂得吧?

而且只要用高精乘低精和高精减就可以了咯

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

 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 out(){
13         if(a[0]==0)putchar('0');
14         for(int i=a[0];i>=1;i--)putchar(a[i]+'0');
15         puts("");
16     }
17     void set_length(int len){
18         a[0]=len;
19     }
20     int length(){
21         return a[0];
22     }
23 };
24 void operator *= (Hyper_long &x,int y){
25     long long r=0;
26     for(int i=1;i<=x.length();i++){
27         x.a[i]=x.a[i]*y+r;
28         r=x.a[i]/10;
29         x.a[i]%=10;
30     }
31     while(r!=0){
32         x.a[0]++;
33         x.a[x.a[0]]=r;
34         r=x.a[x.a[0]]/10;
35         x.a[x.a[0]]%=10;
36     }
37     return ;
38 }
39 Hyper_long operator - (Hyper_long x,Hyper_long y){
40     Hyper_long k(N);
41     int len=max(x.length(),y.length());
42     for(int i=1;i<=len;i++){
43         k.a[i]=x.a[i]-y.a[i];
44         if(k.a[i]<0){
45             x.a[i+1]--;
46             k.a[i]+=10;
47         }
48     }
49     while(1){
50         if(k.a[len]!=0 || len==0) break;
51         len--;
52     }
53     k.set_length(len);
54     return k;
55 }
56 Hyper_long a(N),b(N),c(N);
57 int m,n;
58 int main(){
59     a.a[0]=a.a[1]=1;
60     b.a[0]=b.a[1]=1;
61     scanf("%d%d",&n,&m);
62     for(int i=1;i<=n+2;i++){//先把男生和老师混在一起 
63         a*=i;
64     }
65     for(int i=n+3;i>=n+3-m+1;i--){//把女生插进去 
66         a*=i;
67     }
68     b*=2;//把两个老师绑在一起 
69     for(int i=1;i<=n+1;i++){//和男生混好
70         b*=i;
71     }
72     for(int i=n+2;i>=n+2-m+1;i--){//把女生插进去 
73         b*=i;
74     }
75     c=a-b;
76     c.out();//输出 
77 }
78 
Total Code

 补:如果可以进行式子的处理然后合并同类项:

$A inom{n+1}{n+1} imes A inom{m-1}{n+3} imes (n-m+4)-2 imes A inom{n+1}{n+1} imes A inom{m-1}{n+3} imes (n+2)\ = A inom{n+1}{n+1} imes A inom{m-1}{n+3} imes (n+2) imes (n-m+2) $

就可以实现只用高精乘低精就可以解决的问题了,提出的减法项只用int就可以呢

Miemeng真的蒻
原文地址:https://www.cnblogs.com/kalginamiemeng/p/11109381.html