把解决这个问题理解成解决卡塔兰数的原因是:
检查第一对括号,看有多少括号在它里面和在它外面,分别是f(i)和f(n-i-1)。
所以可以转换成卡塔兰数
问题描述:卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列。输入一个整数n,计算h(n)。其递归式如下:h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2,h(0) = h(1) = 1) 该递推关系的解为:h(n)=C(2n,n)/(n+1) (n=1,2,3,...)
//函数功能: 计算Catalan的第n项
//函数参数: n为项数
//返回值: 第n个Catalan数
int Catalan(int n)
{
if(n <= 1)
return 1;
int *h = new int [n+1]; //保存临时结果
h[0] = h[1] = 1; //h(0)和h(1)
for(int i = 2; i <= n; i++) //依次计算h(2),h(3)...h(n)
{
h[i] = 0;
for(int j = 0; j < i; j++) //根据递归式计算 h(i)= h(0)*h(i-1)+h(1)*h(i-2) + ... + h(i-1)h(0)
h[i] += (h[j] * h[i-1-j]);
}
int result = h[n]; //保存结果
delete [] h; //注意释放空间
return result;
}
#include <iostream>
#include <vector>
using namespace std;
//Print the legal combination
void PrintBrackets(const vector<char> & brackets)
{
for (vector<char>::const_iterator it = brackets.begin(); it != brackets.end(); ++it)
cout << *it <<" ";
cout <<endl;
}
// bracketsNum: the sum of left bracket and right bracket
void MatchBrackets(int bracketsNum, vector<char> & brackets)
{
int left (0), right(0);
for (vector<char>::iterator it = brackets.begin(); it != brackets.end(); ++it)
{
if ('(' == *it) left ++;
else right ++;
}
// The num of left bracket should not be less than the number of right bracket at any position
if (right > left) return;
if (left == right && left + right == bracketsNum)
{
PrintBrackets(brackets);
return ;
}
if (left + right >= bracketsNum)
{
return ;
}
// The number of left bracket equal to the number of right bracket,
// so we can only append the left bracket '(' now.
if (left == right)
{
brackets.push_back('(');
MatchBrackets(bracketsNum, brackets);
brackets.pop_back();
}
// The number of the left bracket equal to bracketsNum/2
// no need to append '('.
else if (bracketsNum - left == right)
{
brackets.push_back(')');
MatchBrackets(bracketsNum, brackets);
brackets.pop_back();
}
// It`s legal to append '(' and ')'
else
{
brackets.push_back('(');
MatchBrackets(bracketsNum, brackets);
brackets.pop_back();
brackets.push_back(')');
MatchBrackets(bracketsNum, brackets);
brackets.pop_back();
}
}
int main()
{
int braNum;
while (cin>> braNum && braNum)
{
vector<char> brackets;
MatchBrackets(braNum, brackets);
}
return 0;
}