HDU 1130 How Many Trees?(卡特蘭數+大數)
阿新 • • 發佈:2019-01-01
How Many Trees?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Problem Description A binary search tree is a binary tree with root k such that any node v reachable from its left has label (v) <label (k) and any node w reachable from its right has label (w) > label (k). It is a search structure which can find a node with label x in O(n log n) average time, where n is the size of the tree (number of vertices).
Given a number n, can you tell how many different binary search trees may be constructed with a set of numbers of size n such that each element of the set will be associated to the label of exactly one node in a binary search tree?
Input The input will contain a number 1 <= i <= 100 per line representing the number of elements of the set.
Output You have to print a line in the output for each entry with the answer to the previous question.
Sample Input 1 2 3
Sample Output 1 2 5 /************************************************************************/
題意:首先題目介紹了二叉搜尋樹的概念(即在一棵二叉樹中,以任意結點為根時,它的左孩子的值都小於根的值,它的右孩子的值總是大於根自身的值,這樣的二叉樹就是二叉搜尋樹),然後給你一個數字n,讓你將1~n這n個數字填到結點上,問能使它成為一棵二叉搜尋樹的填法有多少種
首先,題目已經給出了n=1,n=2,n=3的解,我們不妨再算算看n=4的解:
①以數字1為整棵樹的根,那麼有如下5種情況
②以數字2為整棵樹的根,則有如下2種情況
③以數字3為整棵樹的根,因為與②是對稱的,所以同樣有2種情況,而以數字4為根則與①是對稱的,所以有5種情況
共計14種情況
那麼答案形成的就是這樣一個數列
1,2,5,14……
相信知道卡特蘭數的人此時都會有種似曾相識的感覺,沒錯,這就是卡特蘭數數列,不知道卡特蘭數的,可以點連結學習學習
而我們真正需要的就是卡特蘭數中的一個遞推式
其餘就是模擬大數乘法與除法的過程,詳細見程式碼,不明白的歡迎提出
菜鳥成長記#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<stack> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 101; const int inf = 2147483647; const int mod = 2009; int s[N][2*N]; int main() { int n,i,j,res; s[1][1]=1;s[1][0]=1; for(i=2;i<N;i++) { for(j=1;j<=s[i-1][0];j++) { s[i][j]+=s[i-1][j]*(4*i-2); s[i][j+1]+=s[i][j]/10; s[i][j]%=10; } while(s[i][j]) { s[i][j+1]+=s[i][j]/10; s[i][j]%=10; j++; } for(s[i][0]=--j,res=0;j>0;j--) { res=res*10+s[i][j]; s[i][j]=res/(i+1); res%=(i+1); } while(!s[i][s[i][0]]) s[i][0]--; } while(~scanf("%d",&n)) { for(i=s[n][0];i>0;i--) printf("%d",s[n][i]); puts(""); } return 0; }