[AHOI2012]树屋阶梯

问题 E: [AHOI2012]树屋阶梯

时间限制: 1 Sec  内存限制: 128 MB

题目描述

暑假期间,小龙报名了一个模拟野外生存作战训练班来锻炼体魄,训练的第一个晚上,教官就给他们出了个难题。由于地上露营湿气重,必须选择在高处的树屋露营。小龙分配的树屋建立在一颗高度为N+1尺(N为正整数)的大树上,正当他发愁怎么爬上去的时候,发现旁边堆满了一些空心四方钢材(如图1.1),经过观察和测量,这些钢材截面的宽和高大小不一,但都是1尺的整数倍,教官命令队员们每人选取N个空心钢材来搭建一个总高度为N尺的阶梯来进入树屋,该阶梯每一步台阶的高度为1尺,宽度也为1尺。如果这些钢材有各种尺寸,且每种尺寸数量充足,那么小龙可以有多少种搭建方法?(注:为了避免夜里踏空,钢材空心的一面绝对不可以向上。)
""

   以树屋高度为4尺、阶梯高度N=3尺为例,小龙一共有如图1.2所示的5

   搭 建方法:

   ""

输入

一个正整数 N(1N500),表示阶梯的高度

输出

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

样例输入

3

样例输出

5

提示

1  ≤N500

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 }

 

 

 

posted @ 2017-08-26 21:19  Forever_goodboy  阅读(237)  评论(0编辑  收藏  举报