[AHOI2012]树屋阶梯
问题 E: [AHOI2012]树屋阶梯
时间限制: 1 Sec 内存限制: 128 MB题目描述
暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题。由于地上露营湿气重,必须选择在高处的树屋露营。小龙分配的树屋建立在一颗高度为N+1尺(N为正整数)的大树上,正当他发愁怎么爬上去的时候,发现旁边堆满了一些空心四方钢材(如图1.1),经过观察和测量,这些钢材截面的宽和高大小不一,但都是1尺的整数倍,教官命令队员们每人选取N个空心钢材来搭建一个总高度为N尺的阶梯来进入树屋,该阶梯每一步台阶的高度为1尺,宽度也为1尺。如果这些钢材有各种尺寸,且每种尺寸数量充足,那么小龙可以有多少种搭建方法?(注:为了避免夜里踏空,钢材空心的一面绝对不可以向上。)
以树屋高度为4尺、阶梯高度N=3尺为例,小龙一共有如图1.2所示的5种
搭 建方法:
输入
一个正整数 N(1≤N≤500),表示阶梯的高度
输出
一个正整数,表示搭建方法的个数。(注:搭建方法个数可能很大。)
样例输入
3
样例输出
5
提示
1 ≤N≤500
solution:
这题明显卡特兰数,然而我还傻傻的打了个暴搜去找规律,数论真是个大坑。不过需要高精度,于是把高精度这个坑补了一下,code上自带高精的各种运算。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 #define M 10 7 #define P 1 8 __attribute__((optimize("O3")))int read() { 9 int s=0,f=1; 10 char ch=getchar(); 11 for(; ch<'0'||ch>'9'; ch=getchar()) { 12 if(ch=='-') { 13 f=-1; 14 } 15 } 16 for(; ch>='0'&&ch<='9'; ch=getchar()) { 17 s=(s<<1)+(s<<3)+(ch^48); 18 } 19 return s*f; 20 } 21 struct BigNum { 22 int n[5000],l,Y; 23 BigNum() { 24 l=1,memset(n,0,sizeof(n)); 25 } 26 //---------------------------------- 27 __attribute__((optimize("O3")))void init() { 28 string s; 29 cin>>s; 30 int now=0,ct=0,c1=1; 31 for(int i=s.length()-1; i>=0; i--) { 32 n[now]+=(s[i]-'0')*c1; 33 c1*=10; 34 ct++; 35 if(ct==P&&i!=0) { 36 now++; 37 c1=1; 38 ct=0; 39 } 40 } 41 l=now+1; 42 } 43 //----------------------------------- 44 __attribute__((optimize("O3")))void print() { 45 printf("%d",n[l-1]); 46 for(int i=l-2; i>=0; i--) 47 printf("%0*d",P,n[i]); 48 printf("\n"); 49 } 50 //------------------------------------ 51 BigNum operator +(BigNum x)const { 52 BigNum t=*this; 53 if(x.l>t.l)t.l=x.l; 54 for(int i=0; i<t.l; i++) { 55 t.n[i]+=x.n[i]; 56 if(t.n[i]>=M) { 57 t.n[i+1]+=t.n[i]/M; 58 t.n[i]%=M; 59 } 60 } 61 while(t.n[t.l]) { 62 t.n[t.l+1]+=t.n[t.l]/M; 63 t.n[t.l++]%=M; 64 } 65 return t; 66 } 67 //-------------------------------------- 68 __attribute__((optimize("O3")))bool operator < (BigNum x) const { 69 BigNum t=*this; 70 if(t.l!=x.l)return t.l<x.l; 71 for(int i=t.l-1; i>=0; i--) { 72 if(t.n[i]!=x.n[i])return t.n[i]<x.n[i]; 73 } 74 return 0; 75 } 76 BigNum operator -(BigNum x)const { 77 BigNum t=*this; 78 if(t<x) { 79 printf("-"); 80 swap(t,x); 81 } 82 for(int i=0; i<t.l; i++) { 83 t.n[i]-=x.n[i]; 84 if(t.n[i]<0) { 85 t.n[i]+=M; 86 --t.n[i+1]; 87 } 88 } 89 while(!t.n[t.l-1]&&t.l>1)t.l--; 90 return t; 91 } 92 //-------------------------------------------- 93 BigNum operator * (BigNum x) const { 94 BigNum c,t=*this; 95 c.l=t.l+x.l-1; 96 for(int i=0; i<t.l; i++) 97 for(int j=0; j<x.l; j++) { 98 c.n[i+j]+=t.n[i]*x.n[j]; 99 if(c.n[i+j]>=M) { 100 c.n[i+j+1]+=c.n[i+j]/M; 101 c.n[i+j]%=M; 102 } 103 } 104 while(c.n[c.l]) { 105 c.n[c.l+1]+=c.n[c.l]/M; 106 c.n[c.l++]%=M; 107 } 108 return c; 109 } 110 BigNum operator * (int x) const { 111 BigNum t=*this,c; 112 c.l=t.l; 113 for(int i=0; i<t.l; i++) { 114 c.n[i]+=t.n[i]*x; 115 if(c.n[i]>=M) { 116 c.n[i+1]+=c.n[i]/M; 117 c.n[i]%=M; 118 } 119 } 120 while(c.n[c.l]) { 121 c.n[c.l+1]+=c.n[c.l]/M; 122 c.n[c.l++]%=M; 123 } 124 return c; 125 } 126 //-------------------------------------------- 127 __attribute__((optimize("O3")))void Add(int x) { 128 if(x||l)n[l++]=x; 129 } 130 __attribute__((optimize("O3")))void Re() { 131 reverse(n,n+l); 132 } 133 BigNum operator /(const BigNum &x)const { 134 BigNum t=*this,r,y; 135 y.l=0,r.l=t.l; 136 for(int i=t.l-1; i>=0; --i) { 137 y.Add(t.n[i]); 138 y.Re(); 139 while(!(y<x))y=y-x,r.n[i]++; 140 while(!y.n[y.l-1] && y.l>1)--y.l; 141 y.Re(); 142 } 143 while(!r.n[r.l-1] && r.l>1)--r.l; 144 return r; 145 } 146 BigNum operator /(const int &x)const { 147 BigNum t=*this,r; 148 r.l=t.l; 149 int tmp=0; 150 for(int i=t.l-1; i>=0; --i) { 151 tmp+=t.n[i]; 152 if(tmp>=x) 153 r.n[i]+=tmp/x,tmp%=x; 154 tmp*=M; 155 } 156 while(!r.n[r.l-1] && r.l>1)--r.l; 157 return r; 158 } 159 //--------------------------------------- 160 161 } ans; 162 int n; 163 int main() { 164 n=read(); 165 ans.l=1; 166 ans.n[0]=1; 167 for(int i=2*n;i>n;--i){ 168 ans=ans*i; 169 } 170 for(int i=2;i<=n;++i){ 171 ans=ans/i; 172 } 173 ans=ans/(n+1); 174 ans.print(); 175 return 0; 176 }