[AHOI2012]树屋阶梯

题目描述

输入输出格式

输入格式:

一个正整数N(1<=N<=500),表示阶梯的高度。

输出格式:

一个正整数,表示搭建方法的个数。(注:搭建方法的个数可能很大)

输入输出样例

输入样例#1: 复制
3
输出样例#1: 复制
5

说明

40%的数据:1<=N<=20

80%的数据:1<=N<=300

100%的数据:1<=N<=500

转载自Navi_Gayson:http://www.cnblogs.com/NaVi-Awson/p/7748308.html

我们令$C_n$表示用$n$个长方形拼成$size$为$n$的三角梯形的方案数。

如题中的图,我们枚举最左下角的点属于哪个长方形。显然有$n$种可能,每种方法又把剩下的部分分成两个三角梯形($size$可能为$0$)。

显然我们得到

$$Catalan_n = \sum _{i = 0} ^{n-1} Catalan_i * Catalan_{n-1-i}$$

其实就是$Catalan$的递推式,我们用通项公式求$Catalan_n$即可。

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

学习一下Catalan,顺便复习一下重载运算符

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int n;
 8 struct Big_num
 9 {
10   int a[10005],len;
11   Big_num(){}
12   Big_num &operator *= (const int &b)
13   {int i;
14     for (i=1;i<=len;i++)
15       a[i]*=b;
16     for (i=1;i<=len;i++)
17       a[i+1]+=a[i]/10,a[i]%=10;
18     while (a[len+1]) 
19       {
20     len++;
21     a[len+1]+=a[len]/10;
22     a[len]%=10;
23       }
24   }
25   Big_num &operator /=(const int b)
26   {
27     int now=0,i;
28     Big_num ans;
29     for (i=len;i>=1;i--)
30     {
31       now=now*10+a[i];
32       if (now>=b) ans.a[i]=now/b,now%=b;
33       else ans.a[i]=0;
34     }
35     while (ans.a[len]==0)
36     len--;
37     for (i=1;i<=len;i++) a[i]=ans.a[i];
38    }
39   void print()
40   {int i;
41     for (i=len;i>=1;i--)
42       printf("%d",a[i]);
43     cout<<endl;
44   }
45 }Ans;
46 int main()
47 {int i;
48   cin>>n;
49   Ans.len=Ans.a[1]=1;
50   for (i=n+2;i<=2*n;i++) Ans*=i;
51   for (i=2;i<=n;i++)
52     Ans/=i;
53   Ans.print();
54 }

 

posted @ 2017-10-31 20:46  Z-Y-Y-S  阅读(348)  评论(0编辑  收藏  举报