HDU 6299(多校第一场B)(贪心)

传送门

题面:

Balanced Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1188    Accepted Submission(s): 281

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个“(”或者“)”的字符串,问你用哪种方法把他们相接之后可以使得构成的完美的括号最长。

题目分析:

    这个题其实在贪心的策略上比较类似CF990C这题。

    首先要明白一个事实,两个字符串如果能配出完美的符号,则必定是存在某一个字符串有多余的“(”,另一个字符串有多余的“)”。因此我们首先需要将一个字符串种的完整的括号先预处理出来,之后我们就可以得到一些可以进行拼接的串。

    其次我们需要发现,如果在拼接的过程中(假设我们不断的向右拼接),如果“)”较多,则在之后的匹配过程中,这一部分“)”就浪费了。

    因此我们对于两个串,我们考虑如下的贪心策略。

    1.左括号少于右括号时,尽可能让右括号多的排在前面,若此时右括号相同,再优先将左括号少的排在前面。

    2.左括号多于右括号时,也尽可能让右括号多的排在前面,同时如果此时右括号相同,再优先将左括号少的排在前面。

    3.左右括号数相同等时,将数量多的排在前面。

    4.如果遇到以上三种混合的情况,按照1->2->3的优先级进行排序。

代码:

#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
struct black{
    int lb,rb,sum;
}q[maxn];
bool cmp(black a,black b){//对大小进行贪心排序
    if(a.lb>=a.rb&&b.lb<b.rb) return false;
    if(a.lb<a.rb&&b.lb>=b.rb) return true;
    if(a.lb>=a.rb&&b.lb>=b.rb) return a.rb>b.rb;
    return a.lb<b.lb;
}
char str[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        memset(q,0,sizeof(q));
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s",str);
            int len=strlen(str);
            for(int j=0;j<len;j++){
                if(str[j]=='('){
                    q[i].rb++;
                }
                else{
                    if(q[i].rb>0){
                        q[i].rb--;
                        q[i].sum++;
                    }
                    else q[i].lb++;
                }
            }
        }
        sort(q,q+n,cmp);
        int nowr=0,ans=0;
        for(int i=0;i<n;i++){
            if(q[i].lb>nowr){
                q[i].lb=nowr;
            }
            ans+=q[i].lb+q[i].sum;
            nowr-=q[i].lb;
            nowr+=q[i].rb;
        }
        cout<<ans*2<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_39453270/article/details/81177988
今日推荐