2018 Multi-University Training Contest 1 Balanced Sequence(贪心)

题意:

t组测试数据,每组数据有 n 个只由 '(' 和 ')' 构成的括号串。

要求把这 n 个串排序然后组成一个大的括号串,使得能够匹配的括号数最多。

如()()答案能够匹配的括号数是 4,(()) 也是 4。

例如:

n = 2

)

)((

你可以将其排序为))((,数目为0,也可以将其排序为)((),数目为1。

解法:

贪心。

把所有字符串中本身能够匹配的括号全部去掉,然后剩下的字符串只有三种:

1、全是 '('

2、全是 ')'

3、一串 ')' 加一串 '('

对于每一种字符串,如果 '(' 的数目多于 ‘)’,就把它放在前面,按照字符串中的 ‘)’ 从小到大排序。

         如果 ')' 的数目多于 ‘(’,就把它放在后面,按照字符串中的 ‘(’ 从大到小排序。

然后统计新串合法的括号数即可。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <algorithm>

using namespace std;

#define maxn 100000 + 100

struct stringS
{
    int x, y;
};

bool cmp(stringS a, stringS b)
{
    if (a.x <= a.y && b.x > b.y) return false;
    if (a.x > a.y && b.x <= b.y) return true;
    if (a.x <= a.y && b.x <= b.y) return a.x > b.x;
    if (a.x > a.y && b.x > b.y) return a.y < b.y;
}

int main()
{
    int t;
    scanf("%d", &t);
    for (int ca = 1; ca <= t; ca++)
    {
        int n;
        scanf("%d", &n);

        stringS s[maxn];
        int ans = 0;

        for (int i = 1; i <= n; i++)
        {
            char str[maxn];
            scanf("%s", str);

            s[i].x = 0, s[i].y = 0;
            for (int j = 0; str[j] != '\0'; j++)
                if (str[j] == ')')
                {
                    if (s[i].x) {s[i].x--; ans++;}
                        else s[i].y++;
                }
                else s[i].x++;
        }

        sort(s+1, s+1+n, cmp);

        int instack = 0;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= s[i].y; j++)
                if (instack) {instack--; ans++;}

            for (int j = 1; j <= s[i].x; j++)
                instack++;
        }

        printf("%d\n", ans * 2);
    }
}

猜你喜欢

转载自www.cnblogs.com/ruthank/p/9371156.html