n对括号有多少种匹配方式

把解决这个问题理解成解决卡塔兰数的原因是:

检查第一对括号,看有多少括号在它里面和在它外面,分别是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;  
}  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值