[AHOI2012]树屋阶梯
题目描述
输入输出格式
输入格式:一个正整数N(1<=N<=500),表示阶梯的高度。
输出格式:一个正整数,表示搭建方法的个数。(注:搭建方法的个数可能很大)
输入输出样例
说明
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 }