HDU 6299 Balanced Sequence <<贪心

题意

给出至多1e5个长度不超过1e5的括号序列,问将他们排序重组后最多能有多少对合法括号

思路

先将已经匹配的括号全部去掉,然后我们的序列就只会剩下三种形式——$"((((("$,$"))))((("$,$"))))"$,然后这时候就只有序列的左右括号的数量起作用了,所以我们只需通过这个条件来对他们进行排序,具体来讲,全是左括号的放最左边,全是右括号的放最右边,中间的看他怎么拼起来多怎么放。代码实现上,如果直接按这个思路写的话会re到死。。。具体在下面代码里说明,最后我是借鉴网上大佬的。最后把排好序的序列们扫一边即可。细节上,记得cin关同步,因为输入量还是挺大的。

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+7;
 4 struct Point{
 5     int l,r;
 6     bool operator <(const Point &a) const{
 7         //if(r==0||a.l==0) return true; 原本的写法
 8         //if(l==0||a.r==0) return false; 在sort的时候会出错
 9         //return r+a.l>l+a.r;
10         if(min(l,a.r)==min(r,a.l)) return l>a.l;
11         return min(l,a.r)>min(r,a.l);
12     }
13 }pt[maxn];
14 
15 int main()
16 {
17     std::ios::sync_with_stdio(false);
18     cin.tie(NULL);
19     int T;
20     cin>>T;
21     while(T--)
22     {
23         int n;
24         cin>>n;
25         string str;
26         int ans=0;
27         for(int i=0;i<n;i++)
28         {
29             pt[i].l=pt[i].r=0;
30             cin>>str;
31             for(int j=0;j<str.length();j++)
32             {
33                 if(str[j]=='(')
34                     pt[i].l++;
35                 else{
36                     if(pt[i].l)
37                         pt[i].l--,ans++;
38                     else pt[i].r++;
39                 }
40             }
41         }
42         sort(pt,pt+n);
43         int ansl=0,ansr=0;
44         for(int i=0;i<n;i++)
45         {
46             if(ansl)
47             {
48                 ans+=min(ansl,pt[i].r);
49                 ansl-=pt[i].r;
50                 if(ansl<0) ansl=0;
51             }
52             ansl+=pt[i].l;
53         }
54         cout<<ans*2<<endl;
55     }
56     return 0;
57 }
原文地址:https://www.cnblogs.com/computer-luo/p/10103995.html