我第一次知道卡特兰数是在这样一道题中:
Supposethe coming sequence into a stack is: 1,2,3,4……n . Writea function to print all the possibilities of output sequence.
我是用最笨的深搜dfs来做的。代码如下:
#include "stdafx.h"
#include <stack>
#include <queue>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
int n = 0;
typedef stack<int> Stack;
typedef queue<int> Queue;
void dfs(int level,Stack s, Queue buf, const int LEVEL);
void dfs(int level,Stack s, Queue buf, const int LEVEL)
{
if (level == LEVEL)
{
// whether the last one goes into print queue
// or goes into stack
// has the same effect
buf.push(level);
while(!buf.empty())
{
cout<<buf.front()<<" ";
buf.pop();
}
while(!s.empty())
{
cout << s.top()<<" ";
s.pop();
}
cout<<endl;
n++;
return;
}
Stack tempStack(s);
Queue tempQueue(buf);
tempStack.push(level);
Stack tempStack2 = tempStack;
while(!tempStack.empty())
{
tempQueue.push(tempStack.top());
tempStack.pop();
dfs(level+1, tempStack, tempQueue, LEVEL);
}
dfs(level+1, tempStack2, buf, LEVEL);
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int cases;
int x;
scanf_s("%d", &cases);
while(cases--)
{
Stack s = Stack();
Queue q = Queue();
cin>>x;
dfs(1, s, q, x);
cout<<"the catalan number of "<<x<<" is "<<n<<endl;
n=0;
}
system("pause");
}
当我查阅百度百科“卡特兰数”条目之后,发现卡特兰数不仅和出栈顺序关联,还有这些最基本应用:
设h(n)代表
① 括号化问题:矩阵链乘法:N个矩阵有多少种括号化方案?-------h(n)
② 出栈顺序的变形:在圆上选择2n个点,将这些点成对连接起来,使得所得到的n条线段不相交的方法数;有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)
③ 将一个凸多边形区域分成三角形区域的方法数?
④ 给定N个节点,能构成多少种形状不同的二叉树?
先取一个点作为顶点,然后左边依次可以取0至N-1个相对应的,右边是N-1到0个,两两配对相乘,就是h(0)*h(n-1) + h(2)*h(n-2) + + h(n-1)h(0)=h(n)
我有这样一个想法:能不能用二叉树优化打印序列?(不用把庞大的stack和queue当做参数传递。只要把每一种构型的二叉树遍历一下就好啦。)