hdu -6299 Balanced Sequence

Balanced Sequence


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

 

Source

2018 Multi-University Training Contest 1

 

题意:给出n个字符串,字符串的顺序可随意变换,问组成括号匹配数量 。(自己读题能力太弱,一开始以为字符串内部可排序)

思路:队友们说是贪心,自己没想出来最后看了别人题解https://blog.csdn.net/albertluf/article/details/81177400

先把字符串内部匹配的消掉,则所以字符串都剩下 ”((( 、)))、)))((( “ 三种情况。因此只要以最优的方法排序,就能得到最大的匹配数量,怎么排序呢?将字符串分成 nl >= nr 和 nl < nr 两类, 对于第一类,nr 小的在前面,对于第二类,nl 小的在前面

 

一些代码规范:strlen() 和 st.size() 之类的函数,不要放在循环判断条件。容易超时

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;
const int maxn = 1e5+7;
struct Node
{
    int l,r;
} node[maxn];
bool cmp(Node a, Node b)
{
    if(a.r == 0)
        return 1;
    if(b.r == 0)
        return 0;
    if(a.l >= a.r && b.l<b.r)
        return 1;
    if(a.l < a.r && b.l >= b.r)
        return 0;

    if(a.l >= a.r && b.l >= b.r)
        return a.r<=b.r;
    return a.l >= b.l;
}
char st[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int ans = 0;
        for(int i=0; i<n; i++)
        {
            scanf("%s",st);
            int len = strlen(st);
            node[i].l = 0;
            node[i].r = 0;
            for(int j=0; j<len; j++)
            {

                if(st[j] == ')')
                {
                    if(node[i].l <= 0)
                    {
                        node[i].r++;
                    }
                    else
                    {
                        node[i].l--,ans++;
                    }
                }
                else
                    node[i].l++;
            }
        }
        sort(node,node+n,cmp);

        int l=0;
        for(int i=0; i<n; i++)
        {
            if(node[i].r<=l)
                ans+=node[i].r,l-=node[i].r;
            else ans+=l,l=0;
            l += node[i].l;
        }

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值