HDU 1100 Trees Made to Order (Catalan数)
2012-08-23 19:03
344 查看
#include <iostream> #include <stdio.h> using namespace std; int catalan[19]={ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700}; int catalan_sum[19]={1, 2, 4, 9, 23, 65, 197, 626, 2056, 6918, 23714, 82500, 290512, 1033412, 3707852, 13402697, 48760367, 178405157, 656043857}; int n,x; void f(int k,int n)//k是要求的树中的节点数,n是要求的树在k个节点的树的排列中的序号,从1开始 { int i; if(k<=0)return; if(k==1) { cout << "X"; return; } for(i=0;i<=k-1;i++) { if(n<=catalan[i]*catalan[k-1-i])break; n-=catalan[i]*catalan[k-1-i]; } int left = i,right = k-1-i;//计算出左右子树应该有的节点数 n--;//因为我的序号从1开始,而后面要做整除和取余运算,序号要从0开始才能得到正确结果 if(left>0) { cout << "("; f(left,n/catalan[right]+1);//做完取整运算恢复序号从1开始 cout << ")"; } cout << "X"; if(right>0) { cout << "("; f(right,n%catalan[right]+1);//做完取余运算恢复序号从1开始 cout << ")"; } } int main() { while(cin >> n) { if(n==0)break; n++; for(x=0;n>catalan_sum[x];x++); f(x,n-catalan_sum[x-1]); cout << endl; } return 0; }
思路:这道题目的核心是Catalan数,n个节点的二叉树的所有形态个数就是Catalan数的第n项。
n个节点的二叉树的序列增长服从如下规律:左子树节点数0->n-1,右子树每完成一个catalan[i]个数的变换,左子树的序列数加一。左右子树的关系就像两位数中十位和个位的关系。
相关文章推荐
- hdu1100 Trees Made to Order
- HDU 1100 Trees Made to Order
- hdu_1100_Trees_Made_to_Order
- HDU 1100 Trees Made to Order
- hdu 1100 trees made to order
- hdu 1100 Trees Made to Order
- Trees Made to Order_catalan数_2018_2_17
- Combinatorics——HDUOJ 1100 - Trees Made to Order(二叉树 + 卡特兰数)
- hdoj1100 Trees Made to Order(递归+卡特兰数,关于卡特兰数的讲解)
- poj 1095 Trees Made to Order 卡特兰数
- POJ 1095 Trees Made to Order(卡特兰数列)
- poj-1095-Trees Made to Order
- Trees Made to Order [POJ1095]
- Trees Made to Order ZOJ - 1062
- Trees Made to Order
- POJ 1095 Trees Made to Order 已被翻译
- POJ 1095 Trees Made to Order 卡特兰数以及递归分治
- poj1032 Trees made to order 卡特兰数应用
- POJ 1095 Trees Made to Order
- POJ 1095 Trees Made to Order 笔记