BYRBT

有关卡特兰数——HDU上的几道题

做HDU的ACM Step时碰到2.3这恶心的一章了………………除了高精度就是卡特兰数……………………高精度至少会………………卡特兰数这东西完全没听过……………………于是便有一段时间没去管它了……………………近来无事,终于去把这恼火的卡特兰数给学了学……………………

 

(资料大部分摘自百度百科)

 

卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名。

 

(不说废话了………………)

 

卡特兰数:

f(1)=1 f(2)=1 f(n)=f(1)*f(n-1)+f(2)*f(n-2)+……+f(n-2)*f(2)+f(n-1)*f(1)(n>=3)

通项公式:

f(n)=C(2n,n)/(n+1)

 

据说卡特兰数可以解决很多问题………………

 

  1、括号化

  2、出栈次序

  3、凸多边形的三角剖分

  4、给定节点组成二叉树(都是百科上的………………)

 

其实卡特兰数是一个组合数学里面非常有用的东西,应该算比较基础的了,下面贴几道HDU上的跟卡特兰数有关的题……………………

 

卡特兰数裸题:

HDU1130——How Many Trees?

HDU1134——Game of Connections

 

扩展卡特兰数:

HDU1267——下沙的沙子有几粒?

HDU2067——小兔的棋盘

(这两道题其实是搞笑的……………………)

HDU1133——Buy the Ticket

(这题才算是真资格的扩展卡特兰数吧………………)

 

目前也只做了这么几道跟卡特兰数有关的题…………………………以后碰到再加上来吧……………………

 

附上代码

HDU 1134

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<algorithm>
  5 
  6 using namespace std;
  7 
  8 struct bign
  9 {
 10     int z[100];
 11     int l;
 12     bign()
 13     {
 14         memset(z,0,sizeof(z));
 15         l=0;
 16     }
 17     void operator=(const int &a)
 18     {
 19         int b=a;
 20         l=0;
 21         while (b!=0)
 22         {
 23             l++;
 24             z[l]=b % 10;
 25             b/=10;
 26         }
 27     }
 28     bign operator*(const int &a)
 29     {
 30         bign ans;
 31         ans=*this;
 32         for (int b=1;b<=l;b++)
 33             ans.z[b]=ans.z[b]*a;
 34         int c=0;
 35         for (int b=1;b<=l;b++)
 36         {
 37             ans.z[b]+=c;
 38             c=ans.z[b]/10;
 39             ans.z[b]%=10;
 40         }
 41         while (c>0)
 42         {
 43             ans.l++;
 44             ans.z[ans.l]=c % 10;
 45             c/=10;
 46         }
 47         return ans;
 48     }
 49     bign operator/(const int &a)
 50     {
 51         bign ans;
 52         ans=*this;
 53         int c=0;
 54         for (int b=l;b>=1;b--)
 55         {
 56             ans.z[b]=(c*10+z[b])/a;
 57             c=c*10+z[b]-ans.z[b]*a;
 58         }
 59         for (ans.l=l;ans.l>=0;ans.l--)
 60             if (ans.z[ans.l]!=0) break;
 61         return ans;
 62     }
 63     void print()
 64     {
 65         for (int a=l;a>=1;a--)
 66             printf("%d",z[a]);
 67         printf("\n");
 68     }
 69     bign operator*(const bign &a)
 70     {
 71         bign ans;
 72         for (int b=1;b<=l;b++)
 73             for (int c=1;c<=a.l;c++)
 74                 ans.z[b+c-1]+=z[b]*a.z[c];
 75         int c=0;
 76         for (int b=1;b<=l+a.l;b++)
 77         {
 78             ans.z[b]+=c;
 79             c=ans.z[b]/10;
 80             ans.z[b]%=10;
 81         }
 82         for (ans.l=l+a.l;ans.l>=1;ans.l--)
 83             if (ans.z[ans.l]!=0) break;
 84         return ans;
 85     }
 86     bign operator+(const bign &a)
 87     {
 88         bign ans;
 89         ans.l=max(l,a.l);
 90         for (int b=1;b<=ans.l;b++)
 91             ans.z[b]=z[b]+a.z[b];
 92         int c=0;
 93         for (int b=1;b<=ans.l;b++)
 94         {
 95             ans.z[b]+=c;
 96             c=ans.z[b] / 10;
 97             ans.z[b]%=10;
 98         }
 99         while (c>0)
100         {
101             ans.l++;
102             ans.z[ans.l]=c % 10;
103             c/=10;
104         }
105         return ans;
106     }
107 }h[102];
108 
109 int main()
110 {
111     h[1]=1;
112     h[2]=1;
113     for (int a=3;a<=101;a++)
114         for (int b=1;b<a;b++)
115             h[a]=h[a]+h[b]*h[a-b];
116     int now;
117     while (~scanf("%d",&now))
118     {
119         if (now==-1) break;
120         h[now+1].print();
121     }
122 
123     return 0;
124 }

 

HDU 1267

View Code
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 
 5 using namespace std;
 6 
 7 long long f[30][30];
 8 
 9 int main()
10 {
11     int n=20,m=20;
12     f[0][0]=1;
13     for (int a=0;a<=m;a++)
14         for (int b=0;b<=n;b++)
15             if ((a!=0 || b!=0) && a>=b)
16             {
17                 f[a][b]=f[a-1][b];
18                 if (b!=0) f[a][b]+=f[a][b-1];
19             }
20     while (~scanf("%d%d",&m,&n))
21         printf("%I64d\n",f[m][n]);
22 
23     return 0;
24 }

 

HDU 2067

View Code
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 long long h[102];
 9 
10 int main()
11 {
12     h[1]=1;
13     h[2]=1;
14     for (int a=3;a<=101;a++)
15         for (int b=1;b<a;b++)
16             h[a]=h[a]+h[b]*h[a-b];
17     int a=0;
18     int now;
19     while (~scanf("%d",&now))
20     {
21         if (now==-1) break;
22         a++;
23         printf("%d %d %I64d\n",a,now,h[now+1]*2);
24     }
25 
26     return 0;
27 }

 

HDU 1133

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<algorithm>
  5 
  6 using namespace std;
  7 
  8 struct bign
  9 {
 10     int z[2000];
 11     int l;
 12     bign()
 13     {
 14         memset(z,0,sizeof(z));
 15         l=0;
 16     }
 17     void operator=(const int &a)
 18     {
 19         int b=a;
 20         l=0;
 21         while (b!=0)
 22         {
 23             l++;
 24             z[l]=b % 10;
 25             b/=10;
 26         }
 27     }
 28     bign operator*(const int &a)
 29     {
 30         bign ans;
 31         ans=*this;
 32         for (int b=1;b<=l;b++)
 33             ans.z[b]=ans.z[b]*a;
 34         int c=0;
 35         for (int b=1;b<=l;b++)
 36         {
 37             ans.z[b]+=c;
 38             c=ans.z[b]/10;
 39             ans.z[b]%=10;
 40         }
 41         while (c>0)
 42         {
 43             ans.l++;
 44             ans.z[ans.l]=c % 10;
 45             c/=10;
 46         }
 47         return ans;
 48     }
 49     bign operator/(const int &a)
 50     {
 51         bign ans;
 52         ans=*this;
 53         int c=0;
 54         for (int b=l;b>=1;b--)
 55         {
 56             ans.z[b]=(c*10+z[b])/a;
 57             c=c*10+z[b]-ans.z[b]*a;
 58         }
 59         for (ans.l=l;ans.l>=0;ans.l--)
 60             if (ans.z[ans.l]!=0) break;
 61         return ans;
 62     }
 63     void print()
 64     {
 65         for (int a=l;a>=1;a--)
 66             printf("%d",z[a]);
 67         printf("\n");
 68     }
 69     bign operator*(const bign &a)
 70     {
 71         bign ans;
 72         for (int b=1;b<=l;b++)
 73             for (int c=1;c<=a.l;c++)
 74                 ans.z[b+c-1]+=z[b]*a.z[c];
 75         int c=0;
 76         for (int b=1;b<=l+a.l;b++)
 77         {
 78             ans.z[b]+=c;
 79             c=ans.z[b]/10;
 80             ans.z[b]%=10;
 81         }
 82         for (ans.l=l+a.l;ans.l>=1;ans.l--)
 83             if (ans.z[ans.l]!=0) break;
 84         return ans;
 85     }
 86     bign operator+(const bign &a)
 87     {
 88         bign ans;
 89         ans.l=max(l,a.l);
 90         for (int b=1;b<=ans.l;b++)
 91             ans.z[b]=z[b]+a.z[b];
 92         int c=0;
 93         for (int b=1;b<=ans.l;b++)
 94         {
 95             ans.z[b]+=c;
 96             c=ans.z[b] / 10;
 97             ans.z[b]%=10;
 98         }
 99         while (c>0)
100         {
101             ans.l++;
102             ans.z[ans.l]=c % 10;
103             c/=10;
104         }
105         return ans;
106     }
107 }ans;
108 
109 int main()
110 {
111     int t=0;
112     int n,m;
113     while (~scanf("%d%d",&m,&n))
114     {
115         if (m==0 && n==0) break;
116         t++;
117         printf("Test #%d:\n",t);
118         ans=1;
119         if (m<n) printf("0\n");
120         else
121         {
122             for (int a=2;a<=m+n;a++)
123                 ans=ans*a;
124             ans=ans*(m-n+1);
125             ans=ans/(m+1);
126             ans.print();
127         }
128     }
129 
130     return 0;
131 }

 

HDU 1130

 

View Code
  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<algorithm>
  5 
  6 using namespace std;
  7 
  8 struct bign
  9 {
 10     int z[100];
 11     int l;
 12     bign()
 13     {
 14         memset(z,0,sizeof(z));
 15         l=0;
 16     }
 17     void operator=(const int &a)
 18     {
 19         int b=a;
 20         l=0;
 21         while (b!=0)
 22         {
 23             l++;
 24             z[l]=b % 10;
 25             b/=10;
 26         }
 27     }
 28     bign operator*(const int &a)
 29     {
 30         bign ans;
 31         ans=*this;
 32         for (int b=1;b<=l;b++)
 33             ans.z[b]=ans.z[b]*a;
 34         int c=0;
 35         for (int b=1;b<=l;b++)
 36         {
 37             ans.z[b]+=c;
 38             c=ans.z[b]/10;
 39             ans.z[b]%=10;
 40         }
 41         while (c>0)
 42         {
 43             ans.l++;
 44             ans.z[ans.l]=c % 10;
 45             c/=10;
 46         }
 47         return ans;
 48     }
 49     bign operator/(const int &a)
 50     {
 51         bign ans;
 52         ans=*this;
 53         int c=0;
 54         for (int b=l;b>=1;b--)
 55         {
 56             ans.z[b]=(c*10+z[b])/a;
 57             c=c*10+z[b]-ans.z[b]*a;
 58         }
 59         for (ans.l=l;ans.l>=0;ans.l--)
 60             if (ans.z[ans.l]!=0) break;
 61         return ans;
 62     }
 63     void print()
 64     {
 65         for (int a=l;a>=1;a--)
 66             printf("%d",z[a]);
 67         printf("\n");
 68     }
 69     bign operator*(const bign &a)
 70     {
 71         bign ans;
 72         for (int b=1;b<=l;b++)
 73             for (int c=1;c<=a.l;c++)
 74                 ans.z[b+c-1]+=z[b]*a.z[c];
 75         int c=0;
 76         for (int b=1;b<=l+a.l;b++)
 77         {
 78             ans.z[b]+=c;
 79             c=ans.z[b]/10;
 80             ans.z[b]%=10;
 81         }
 82         for (ans.l=l+a.l;ans.l>=1;ans.l--)
 83             if (ans.z[ans.l]!=0) break;
 84         return ans;
 85     }
 86     bign operator+(const bign &a)
 87     {
 88         bign ans;
 89         ans.l=max(l,a.l);
 90         for (int b=1;b<=ans.l;b++)
 91             ans.z[b]=z[b]+a.z[b];
 92         int c=0;
 93         for (int b=1;b<=ans.l;b++)
 94         {
 95             ans.z[b]+=c;
 96             c=ans.z[b] / 10;
 97             ans.z[b]%=10;
 98         }
 99         while (c>0)
100         {
101             ans.l++;
102             ans.z[ans.l]=c % 10;
103             c/=10;
104         }
105         return ans;
106     }
107 }h[102];
108 
109 int main()
110 {
111     h[1]=1;
112     h[2]=1;
113     for (int a=3;a<=101;a++)
114         for (int b=1;b<a;b++)
115             h[a]=h[a]+h[b]*h[a-b];
116     int now;
117     while (~scanf("%d",&now))
118         h[now+1].print();
119 
120     return 0;
121 }

 

 

 

 

posted @ 2012-05-01 16:35  zhonghaoxi  阅读(722)  评论(1编辑  收藏  举报
BYRBT