1. 程式人生 > >bzoj2822[AHOI2012]樹屋階梯(卡特蘭數)

bzoj2822[AHOI2012]樹屋階梯(卡特蘭數)

n+1 amp nbsp put mat pan cat limit 一個

2822: [AHOI2012]樹屋階梯

Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 879 Solved: 513
[Submit][Status][Discuss]

Description

暑假期間,小龍報名了一個模擬野外生存作戰訓練班來鍛煉體魄,訓練的第一個晚上,教官就給他們出了個難題。由於地上露營濕氣重,必須選擇在高處的樹屋露營。小龍分配的樹屋建立在一顆高度為N+1尺(N為正整數)的大樹上,正當他發愁怎麽爬上去的時候,發現旁邊堆滿了一些空心四方鋼材(如圖1.1),經過觀察和測量,這些鋼材截面的寬和高大小不一,但都是1尺的整數倍,教官命令隊員們每人選取N個空心鋼材來搭建一個總高度為N尺的階梯來進入樹屋,該階梯每一步臺階的高度為1尺,寬度也為1尺。如果這些鋼材有各種尺寸,且每種尺寸數量充足,那麽小龍可以有多少種搭建方法?(註:為了避免夜裏踏空,鋼材空心的一面絕對不可以向上。)
技術分享

以樹屋高度為4尺、階梯高度N=3尺為例,小龍一共有如圖1.2所示的5種

搭 建方法:

技術分享

Input

一個正整數 N(1N500),表示階梯的高度

Output

一個正整數,表示搭建方法的個數。(註:搭建方法個數可能很大。)

Sample Input

3

Sample Output

5

HINT

1N500

解析見 http://www.cnblogs.com/Konjakmoyu/p/6605700.html

#include <iostream>
#include 
<stdio.h> #include <cmath> using namespace std; int a[502][502]; //大數卡特蘭數 int b[502]; //卡特蘭數的長度 void catalan() //求卡特蘭數 { int i,j,len,carry,temp; a[1][0]=b[1]=1; len=1; for(i=2;i<=501;i++) { for(j=0;j<len;j++) //乘法 a[i][j]=a[i-1
][j]*(4*(i-1)+2); carry=0; for(j=0;j<len;j++) //處理相乘結果 { temp=a[i][j]+carry; a[i][j]=temp%10; carry=temp/10; } while(carry) //進位處理 { a[i][len++]=carry%10; carry/=10; } carry=0; for(j=len-1;j>=0;j--) //除法 { temp=carry*10+a[i][j]; a[i][j]=temp/(i+1); carry=temp%(i+1); } while(!a[i][len-1]) //高位零處理 len--; b[i]=len; } } int main() { int i,n; catalan(); scanf("%d",&n); for(i=b[n]-1;i>=0;i--) printf("%d",a[n][i]); return 0; }

bzoj2822[AHOI2012]樹屋階梯(卡特蘭數)