做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 }