【HDU 1133】 Buy the Ticket (卡特兰数)

(卡特兰数)hdu1133 <wbr> <wbr>Buy <wbr>the <wbr>Ticket
(卡特兰数)hdu1133 <wbr> <wbr>Buy <wbr>the <wbr>Ticket

【分析】

  

  当m<n,显然一定不合法。

  所以我们考虑m>=n,类比n=m时的方案数推法,总方案为C(m,m+n),要减去不符合的情况。

  我们扫描一个数,找到第一个不符合的位置,假设是有a个1,a+1个1,那么我们后面会填n-a-1个-1,m-a个1,我们把后面的1和-1交换,就得到了一个有m-a个-1,n-a-1个1的数,方案为C(m+1,m+n),把它减掉即可,

  即ans=C(m,m+n)-C(m+1,m+n)。因为每个人不相同最后1还要乘n!*m!。
  为什么要用1和-1互换呢,

  首先对于一个不合法串是唯一对应一个转换串的(就按照上述方法转换),

  然后对于一个转换串是一定对应一个不合法串的,方法是找到其第一个不合法的地方,然后后面部分-1和1转换。

  还有就是转换串一定不合法,因为它有m+1个-1,n-1个1,而m>=n。这就是他比原串优越的地方,用他可以完全取代不合法串!

代码如下:(还没有测,hdu挂掉了)

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<cmath>
 8 using namespace std;
 9 #define Maxn 110
10 
11 struct node
12 {
13     int d[Maxn],ln;
14 };
15 node t[3];
16 
17 void mul(int x,int y)
18 {
19     int add=0;
20     for(int i=1;i<=t[x].ln;i++)
21     {
22         t[x].d[i]*=y;
23         t[x].d[i]+=add;
24         add=t[x].d[i]/10;
25         t[x].d[i]%=10;
26         // if(i==t[x].ln&&t[x].d[i+1]!=0) t[x].ln++;
27     }
28     t[x].d[t[x].ln+1]=add;
29     while(t[x].d[t[x].ln+1]!=0)
30     {
31         t[x].ln++;
32         t[x].d[t[x].ln+1]=t[x].d[t[x].ln]/10;
33         t[x].d[t[x].ln]%=10;
34     }
35 }
36 
37 void get_ans()
38 {
39     t[2].ln=t[0].ln;
40     for(int i=1;i<=t[0].ln;i++)
41     {
42         if(t[0].d[i]<t[1].d[i])
43         {
44             t[0].d[i+1]--;
45             t[0].d[i]+=10;
46         }
47         t[2].d[i]=t[0].d[i]-t[1].d[i];
48     }
49     while(t[2].d[t[2].ln]==0) t[2].ln--;
50     if(t[2].ln==0) t[2].ln++;
51 }
52 
53 int main()
54 {
55     int kase=0;
56     while(1)
57     {
58         int m,n;
59         scanf("%d%d",&m,&n);
60         if(m==0&&n==0) break;
61         printf("Test #%d:
",++kase);
62         if(m<n) {printf("0
");continue;}
63         memset(t[0].d,0,sizeof(t[0].d));
64         memset(t[1].d,0,sizeof(t[1].d));
65         t[0].d[1]=1; t[0].ln=1;
66         for(int i=1;i<=m+n;i++)
67         {
68             mul(0,i);
69         }
70         t[1].d[1]=1; t[1].ln=1;
71         for(int i=1;i<=m;i++)
72         {
73             mul(1,i);
74         }
75         for(int i=m+2;i<=m+n;i++)
76         {
77             mul(1,i);
78         }
79         mul(1,n);
80         get_ans();
81         for(int i=t[2].ln;i>=1;i--) printf("%d",t[2].d[i]);
82         printf("
");
83     }
84     return 0;
85 }
[HDU 1133]

2016-09-07 22:06:16

原文地址:https://www.cnblogs.com/Konjakmoyu/p/5851273.html