Balanced Sequence hdu

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个包含’(‘与’)’的字符串,可以将这些字符串任意排序,求所有排序中,子序列是正规括号序列的最大长度。
思路:首先我们对所有的字符串找到通过stack找到所有的串内正规括号子序列记下ans,之后栈里剩下的串只有三种可能: 
1. 只包含’(’ 
2. 先是一串’)’然后再是一串’(’ 
3. 只包含’)’ 
然后,按照第一类,第二类,第三类的顺序放置串。

对于第二类内的排序,首先按照 ’(‘ 个数贡献正负排序,’)’个数小于’(‘个数则贡献为正,贡献是正的则排前面。然后正贡献的串,我们按照’)’个数从小到大排。负贡献的串,我们按照’(‘个数从大到小排。对于排序完的串,我们从前往后模拟记录一下即可。

代码:

先放上队友的代码, 

#include<bits/stdc++.h>
using namespace std;
char s[100005];
struct node
{
    int st,et;
    bool operator<(const node &aa)const
    {
        return min(st,et)<min(aa.st,aa.et);
    }
};
priority_queue<node>q;
stack<char>c;
int main()
{
    int t,i,j,len,sum,aa,bb,tt,n;
    node now,noww;
    scanf("%d",&t);
    while(t--)
    {
        while(!q.empty())q.pop();
        sum=0;
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%s",&s);
            len=strlen(s);
            for(j=0;j<len;j++)
            {
                if(s[j]==')')
                {
                    if(!c.empty()&&c.top()=='(')
                        c.pop();
                    else
                        c.push(s[j]);
                }
                else
                c.push(s[j]);
            }
            aa=bb=0;
            while(!c.empty())
            {
                if(c.top()=='(')bb++;
                else
                    aa++;
                c.pop();
            }
            sum+=(len-aa-bb)/2;
            now.st=aa;
            now.et=bb;
            q.push(now);
        }
        while(!q.empty())
        {
            now=q.top();
            q.pop();
            if(q.empty())break;
            noww=q.top();
            q.pop();
            //cout<<"ssss"<<endl;
            //("%d %d %d %d\n",now.st,now.et,noww.st,noww.et);
            if(min(noww.et,now.st)>min(noww.st,now.et))
                swap(now.st,noww.st),swap(now.et,noww.et);
            sum+=min(now.et,noww.st);
            if(now.et>noww.st)
            {
                now.et=now.et-noww.st+noww.et;
            }
            else
            {
                now.st+=noww.st-now.et;
                now.et=noww.et;
            }
            if(now.et||now.st)
            q.push(now);
        }
        printf("%d\n",sum*2);
    }
}

再膜一下大佬的代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;
const int MAXN=(int)1e5+10;
struct node
{
    int a,b;
}p[MAXN];
char str[MAXN];
stack<char>s;
vector<node>v1,v2,v3;
bool cmp(node x,node y){
    if(x.a+x.b>=0&&y.a+y.b>=0)return x.a>y.a;
    else if(x.a+x.b>=0)return 1;
    else if(y.a+y.b>=0)return 0;
    else return x.b>y.b;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        while(!s.empty())s.pop();
        v1.clear();v2.clear();v3.clear();
        int step=0,n,ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str);
            for(int j=0;str[j]!='\0';j++)
            {
                if(str[j]=='(')s.push(str[j]);
                else 
                {
                    if(!s.empty()&&s.top()=='(')s.pop(),ans++;
                    else s.push(str[j]);
                }
            }
            int a=0,b=0;    
            while(!s.empty())
            {
                if(s.top()=='(')b++;
                else a--;
                s.pop();
            }
            p[i].a=a;p[i].b=b;
            if(a==0&&b)v1.push_back(p[i]);
            else if(a&&b==0)v3.push_back(p[i]);
            else v2.push_back(p[i]);
        }
        for(int i=0;i<v1.size();i++)
            step+=v1[i].b;
        sort(v2.begin(),v2.end(),cmp);
        for(int i=0;i<v2.size();i++)
        {
            if(step<0)step=0;
            ans+=min(-v2[i].a,step);
            if(step+v2[i].a<0)
            {
                step=v2[i].b;
                continue;
            }
            step+=v2[i].a+v2[i].b;
        }
        for(int i=0;i<v3.size();i++)
        {
            if(step<0)step=0;
            ans+=min(step,-v3[i].a);
            if(step+v3[i].a<0)
            {
                step=0;
                break;
            }
            step+=v3[i].a;
        }
        printf("%d\n",ans*2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37748451/article/details/81187273