[AHOI 2012]树屋阶梯
Description
暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题。由于地上露营湿气重,必须选择在高处的树屋露营。小龙分配的树屋建立在一颗高度为N+1尺(N为正整数)的大树上,正当他发愁怎么爬上去的时候,发现旁边堆满了一些空心四方钢材(如图1.1),经过观察和测量,这些钢材截面的宽和高大小不一,但都是1尺的整数倍,教官命令队员们每人选取N个空心钢材来搭建一个总高度为N尺的阶梯来进入树屋,该阶梯每一步台阶的高度为1尺,宽度也为1尺。如果这些钢材有各种尺寸,且每种尺寸数量充足,那么小龙可以有多少种搭建方法?(注:为了避免夜里踏空,钢材空心的一面绝对不可以向上。)
![](http://www.lydsy.com/JudgeOnline/upload/201305/1(6).jpg)
以树屋高度为4尺、阶梯高度N=3尺为例,小龙一共有如图1.2所示的5种
搭 建方法:
Input
一个正整数 N(1≤N≤500),表示阶梯的高度
Output
一个正整数,表示搭建方法的个数。(注:搭建方法个数可能很大。)
Sample Input
3
Sample Output
5
HINT
1 ≤N≤500
题解
我们令$C_n$表示用$n$个长方形拼成$size$为$n$的三角梯形的方案数。
如题中的图,我们枚举最左下角的点属于哪个长方形。显然有$n$种可能,每种方法又把剩下的部分分成两个三角梯形($size$可能为$0$)。
显然我们得到
$$C_n = \sum _{i = 0} ^{n-1} C_i * C_{n-1-i}$$
其实就是$Catalan$的递推式,我们用通项公式求$C_n$即可。
1 //It is made by Awson on 2017.10.29 2 #include <set> 3 #include <map> 4 #include <cmath> 5 #include <ctime> 6 #include <stack> 7 #include <queue> 8 #include <vector> 9 #include <string> 10 #include <cstdio> 11 #include <cstdlib> 12 #include <cstring> 13 #include <iostream> 14 #include <algorithm> 15 #define LL long long 16 #define Min(a, b) ((a) < (b) ? (a) : (b)) 17 #define Max(a, b) ((a) > (b) ? (a) : (b)) 18 #define Abs(x) ((x) < 0 ? (-(x)) : (x)) 19 using namespace std; 20 const int N = 10005; 21 22 int n; 23 struct BIG_NUM { 24 int a[N+5], len; 25 BIG_NUM() { 26 } 27 BIG_NUM(int* _a, int _len) { 28 len = _len; 29 for (int i = 1; i <= _len; i++) a[i] = _a[i]; 30 } 31 BIG_NUM &operator *= (const int &b) { 32 for (int i = 1; i <= len; i++) a[i] *= b; 33 for (int i = 1; i <= len; i++) a[i+1] += a[i]/10, a[i] %= 10; 34 int loc = len+1; 35 while (a[loc]) { 36 a[loc+1] += a[loc]/10; a[loc] %= 10; loc++; 37 } 38 len = loc-1; 39 } 40 BIG_NUM &operator /= (const int &b) { 41 int r = 0, i; 42 BIG_NUM ans; 43 for (i = len; i >= 1; i--) { 44 r = r*10+a[i]; 45 if (r >= b) break; 46 } 47 ans.len = i; 48 for (i-- ; i >= 1; i--) { 49 ans.a[i+1] = r/b; r = r%b*10+a[i]; 50 } 51 ans.a[1] = r/b; 52 len = ans.len; for (int i = 1; i <= len; i++) a[i] = ans.a[i]; 53 } 54 void print() { 55 for (int i = len; i >= 1; i--) printf("%d", a[i]); 56 printf("\n"); 57 } 58 }A; 59 60 void work() { 61 scanf("%d", &n); 62 A.len = A.a[1] = 1; 63 for (int i = n+2; i <= (n<<1); i++) A *= i; 64 for (int i = 2; i <= n; i++) A /= i; 65 A.print(); 66 } 67 int main() { 68 work(); 69 return 0; 70 }
博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/NaVi-Awson/,否则你会终生找不到妹子!!!