[AHOI2012]樹屋階梯
阿新 • • 發佈:2017-10-31
ostream www. int() tro class ++ 描述 搭建 i++
題目描述
輸入輸出格式
輸入格式:一個正整數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 }
[AHOI2012]樹屋階梯