括号合法匹配数问题

#include<iostream>
using namespace std;
int n;//门数*2,这里为便于编程默认n为偶数
int k;//k种括号
//dg函数返回值表示在第door对括号保持flag状态和noclose个未闭合门数情况下第door+1对括号的位置的可能(主要判断左括号)
int dg(int door,int flag, int noclose)//door 是门的序号,flag为1表示立即闭合,为0表示不立即闭合,noclose是包括此门在内的未闭合门数
{
    if (2 * (door + 1) == n)//相当于一棵树如果从根走到叶子则为一种方法,而对于倒数第二个括号无论是否立即闭合,它的下一对括号(即最后一对括号)的位置都是唯一确定的
        return 1;
    int sum = 0;
    for (int i = 0; i <= noclose; i++)
    {
        sum += dg(door + 1, 1, i);
    }
    return dg(door + 1, 0,noclose+1) + sum;
}
int main()
{
    cin >> n;
    cin >> k;
    int x = n / 2;
    int num = pow(k, x);
    if (n == 2)
    {
        cout << num;
        return 0;
    }
    int cnt = dg(1, 1,0) + dg(1, 0,1);
    int ans = num * cnt;
    cout << ans;
    return 0;
}

题目是n位(n/2对括号,n为偶数),求合法括号安排数。 我的思想: 第x对括号对第x+1对括号的左括号位置的影响仅在于第x对括号是否立即闭合: 1.如果非立即闭合,则第x+1对括号的左括号位置唯一确定,右括号位置可能性与第x+1对括号是否立即闭合有关,这就是递归了 2.如果立即闭合,则第x+1对括号的左括号位置可能性有1+noclose种(noclose是当前未闭合括号数),对于每种,其右括号位置都与其是否立即闭合有关,这又是递归

#include<iostream>
using namespace std;
int n;//门数*2,这里为便于编程默认n为偶数
int k;//k种括号
int dg(int lnum,int rnum)//左括号有lnum个,右括号有rnum个的情况下的合法匹配数
{
    int x=0, y=0;
    if (lnum == n / 2 && rnum == n / 2)
        return 1;
    if (lnum < n/2)//优先加左括号
        x = dg(lnum + 1, rnum);//x是加左括号的合法匹配数
    if (lnum > rnum)//再加右括号
        y = dg(lnum, rnum + 1);//y是加右括号的合法匹配数(与上面加左括号不是互斥关系)
    return x + y;

}
int main()
{
    cin >> n;
    cin >> k;
    int x = n / 2;
    int num = pow(k, x);
    if (n == 2)
    {
        cout << num;
        return 0;
    }
    int cnt = dg(0,0);
    int ans = num * cnt;
    cout << ans;
    return 0;
}

上面这种是我看的一个博主的方法,感觉更简便。 思想: 记录当前的左括号个数和右括号个数,左括号数小于总括号数时加左括号,然后如果左括号数大于右括号数则加右括号**(注意加括号的顺序:先递归加左括号,再递归加右括号)** 左括号数==右括号数==总括号数时为1个合法匹配,返回1。 这个思想也是从根逐渐加左右括号直至成为合法匹配,然后统计这样的情况数量。

全部评论

相关推荐

用户64975461947315:这不很正常吗,2个月开实习证明,这个薪资也还算合理,深圳Java好多150不包吃不包住呢,而且也提前和你说了没有转正机会,现在贼多牛马公司骗你说毕业转正,你辛辛苦苦干了半年拿到毕业证,后面和你说没hc了😂
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务