2018杭电多校第一场B(hdu6299)

题意

给你n个包含’(‘与’)’的字符串,可以将这些字符串任意排序,求所有排序中,子序列是正规括号序列的最大长度。

题解

参考大佬https://blog.csdn.net/ACTerminate/article/details/81171799

首先我们对所有的字符串找到通过stack找到所有的串内正规括号子序列,之后剩下的串只有三种可能: 
1. 只包含’(’ 
2. 先是一串’)’然后再是一串’(’ 
3. 只包含’)’ 
然后,按照第一类,第二类,第三类的顺序放置串。对于第二类内的排序,首先按照’(‘个数贡献正负排序,’)’个数小于’(‘个数则贡献为正,贡献是正的则排前面。然后正贡献的串,我们按照’)’个数从小到大排。负贡献的串,我们按照’(‘个数从大到小排。对于排序完的串,我们从前往后模拟记录一下即可。

注意:对正贡献串排序的时候因为a<0,所以应该return x.a>y.a

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=200005;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
struct node
{
    ll a,b;
};
bool operator <(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()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int t,n;
    cin>>t;
    while(t--)
    {
        vector<node> v1,v2,v3;
        stack<char> st;
        cin>>n;
        ll ans=0;
        for(int i=0; i<n; i++)
        {
            char s[100005];
            cin>>s;
            for(int j=0; j<strlen(s); j++)
            {
                if(s[j]=='(')
                    st.push(s[j]);
                else
                {
                    if(!st.empty()&&st.top()=='(')
                    {
                        st.pop();
                        ans++;
                    }
                    else
                    {
                        st.push(s[j]);
                    }
                }
            }
            int a=0,b=0;//a:')'  b:'('
            while(!st.empty())
            {
                char t=st.top();
                if(t=='(')
                    b++;
                else
                    a--;
                st.pop();
            }
            node t;
            t.a=a,t.b=b;
            if(!b&&a)
            {
                v3.push_back(t);
            }
            else if(!a&&b)
            {
                v1.push_back(t);
            }
            else
            {
                v2.push_back(t);
            }
        }
        ll step=0;
        sort(v2.begin(),v2.end());
        for(int i=0; i<v1.size(); i++)
        {
            step+=v1[i].b;
        }
        for(int i=0; i<v2.size(); i++)
        {
            if(step<0)
            {
                step=0;
            }
            ans+=min(step,-v2[i].a);
            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;
        }
        cout<<ans*2<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dilly__dally/article/details/81319957