HDU6299 Balanced Sequence(2018HDU多校联赛第一场,思路,贪心)

Problem Description

Chiaki has n strings s1,s2,…,sn consisting of ‘(’ and ‘)’. A string of
this type is said to be balanced:

  • if it is the empty string
  • if A and B are balanced, AB is balanced,
  • if A is balanced, (A) is balanced.

Chiaki can reorder the strings and then concatenate them get a new
string t. Let f(t) be the length of the longest balanced subsequence
(not necessary continuous) of t. Chiaki would like to know the maximum
value of f(t) for all possible t.

Input

There are multiple test cases. The first line of input contains an
integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤105) – the number of
strings. Each of the next n lines contains a string si (1≤|si|≤105)
consisting of (' and)’. It is guaranteed that the sum of all |si|
does not exceeds 5×106.

Output

For each test case, output an integer denoting the answer.

Sample Input

2
1
)()(()(
2
)
)(

Sample Output

4
2

思路

一个平衡串,具有以下定义:

  • 串非空
  • 如果两个串是平衡的,那么两个串连接起来也是平衡的
  • 如果一个串是平衡的,那么给他加括号后也是平衡的

其实题目就是给了你n个串,每个串只包含()这两种符号。然后问你把这些串按照一定的顺序拼接起来形成一个长串,定义 f ( t ) 为一个串中的最长平衡子序列的长度,求让这个 f ( t ) 最大的值。

我们首先对于每一个串进行处理,利用一个栈(类似),如果先把每一个串处理一下,把这些串中已经匹配的括号数量计算出来,然后对于每一个串,剩余的串一定是前面若干个符号是)后面若干个括号是(的串。

对于这些串,我们按照其中包含的)的数量进行排序,有四种情况

  1. 第一个串的数量大于( 且 第二个串的)数量小于(,第一个串放在前面
  2. 第一个串的数量小于( 且 第二个串的)数量大于(,第一个串放在后面
  3. 两个串的数量都大于(,则(数量大的放前面
  4. 两个串的数量都小于(,则)数量大的放前面

排序完成后直接对拼接成的串进行计算就好了,屋内问的是 f ( t ) 的长度,而我们算出来的是匹配数,所以最后的结果要乘以 2 .

代码

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <sstream>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
const int N = 5e5 + 10;
const int inf = 0x3f3f3f3f;
struct node
{
    int l, r, add;
} a[N];
char s[N];
bool cmp(node A, node B)
{
    if (A.l >= A.r && B.l < B.r)
        return false;
    if (A.l < A.r && B.l >= B.r)
        return true;
    if (A.l >= A.r && B.l >= B.r)
        return A.r > B.r;
    //if (A.l <= B.r && B.l <= B.r)
    return A.l < B.l;
}
int main()
{
    //freopen("in.txt", "r", stdin);
    int t, n;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            int len = strlen(s);
            a[i].l = a[i].r = a[i].add = 0;
            for (int j = 0; j < len; j++)
            {
                if (s[j] == '(')
                    a[i].r++;
                else
                {
                    if (a[i].r > 0)
                    {
                        a[i].r--;
                        a[i].add++;
                    }
                    else
                        a[i].l++;
                }
            }
        }
        sort(a + 1, a + n + 1, cmp);
        int ans = 0, now = 0;
        for (int i = 1; i <= n; i++)
        {
            if (a[i].l > now)
                a[i].l = now;
            ans += a[i].l + a[i].add;
            now -= a[i].l;
            now += a[i].r;
        }
        printf("%d\n", ans * 2);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/riba2534/article/details/81182944