B - Balanced Sequence HDU - 6299 -贪心+思维

  • B - Balanced Sequence
  •  HDU - 6299 
  • 题意:给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;
    }
    
  •  

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/83959869