1. 程式人生 > >Balanced Sequence HDU

Balanced Sequence HDU

  • 題意:給n個括號字串,reorder改變這n個字串的位置,讓最終匹配的括號數最大
  • 思路:先預處理出原來每個串中匹配的個數,因為無論怎麼動都不會改變它們。
  • 所以結構體記錄每個串中已經匹配的數目,不匹配的‘)‘個數為R,不匹配的’(‘個數為L
  • 接下來就是處理這些沒有匹配的讓它們儘可能多的湊出匹配的來,先分一下情況:
  • 1. 只包含’(’    2. 前面是’)’後面是’(’ .3. 只包含’)’ ,然後,按照第一類,第二類,第三類的順序放置
  • 重構排序函式:
  •     if(a.l>a.r&&b.l>b.r)
            return a.r<b.r;
        if(a.l>a.r)return 1;
        return b.l<=b.r?a.l>b.l:0;
  • 第一優先順序:如果 a與b的 ‘(’數目都大於’)‘數目,那麼它們就需要按照’)‘數目小的在前面
  • 這就包含了上面三類中的第一類與第二類中的 ‘(’數目大於’)‘的部分
  • 第二優先順序為:如果a是一二類中的b是第三類的直接返回1,就是返回a在前面
  • 第三優先順序為:經歷了前兩級說明a一定是第三類或第二類中 ‘(’數目小於’)‘的了,
  • 但是b不確定,判斷如果b是第二類‘(’數目都大於’)‘直接返回0也就是返回b在前面
  • 如果b是第二類中 ‘(’數目小於’)‘的那麼需要與a比較’(‘大的在前面。
  • 然後在模擬一遍括號棧模擬操作求一下個數
  • #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define maxn 125050
    char str[maxn];
    int n,t,ans,sum;
    struct node
    {
        int l,r,s;
    } num[maxn];
    bool cmp(node a,node b)
    {
        if(a.l>a.r&&b.l>b.r)
            return a.r<b.r;
        if(a.l>a.r)return 1;
        return b.l<=b.r?a.l>b.l:0;
    }
    void solve(int orz,int len)
    {
        num[orz].l=num[orz].r=0;
        stack<char>qyn;
        for(int i=0; i<len; i++)
        {
            if(!qyn.empty())
            {
                if(qyn.top()=='('&&str[i]==')')
                    qyn.pop();
                else qyn.push(str[i]);
            }
            else qyn.push(str[i]);
        }
        while(!qyn.empty())
        {
            if(qyn.top()==')')
                num[orz].r++;
            else
                num[orz].l++;
            qyn.pop();
        }
        num[orz].s=len-num[orz].l-num[orz].r;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            sum=ans=0;
            scanf("%d",&n);
            for(int i=0; i<n; i++)
            {
                scanf("%s",str);
                int len=strlen(str);
                solve(i,len);
            }
            sort(num,num+n,cmp);
            stack<char>stk;
            while(!stk.empty())stk.pop();
            for(int i=0; i<n; i++)
            {
                sum+=num[i].l+num[i].r;
                while(num[i].r--)
                {
                    if(!stk.empty())
                    {
                        if(stk.top()=='(')
                            stk.pop();
                        else stk.push(')');
                    }
                    else stk.push(')');
                }
                while(num[i].l--)
                    stk.push('(');
                ans+=num[i].s;
            }
            ans+=(sum-stk.size());
            printf("%d\n",ans);
        }
        return 0;
    }