题意
给你一些括号序列,让你对这些括号序列排序,使得匹配的括号最多。
思路
我们打一个表,寸的是对于一个序列来说他需要多少个左括号和他需要多少个右括号,可以组成匹配的括号,那么我们xjb排个序,然后加起来就好了,显然我们让左括号尽可能的放在前面,对吧,因为这样贪心的和才是最大的。那么我们排序让左括号尽可能的放到前面。,
第一个串的)数量大于( 且 第二个串的)数量小于(,第一个串放在前面
第一个串的)数量小于( 且 第二个串的)数量大于(,第一个串放在后面
两个串的)数量都大于(,则(数量大的放前面
两个串的)数量都小于(,则)数量大的放前面
之后排好序随便搞搞就好了
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
struct node
{
int L,R,ALL;
bool operator <(const node &b) const
{
if(L >= R && b.L < b.R)
return false;
if(L < R && b.L >= b.R)
return true;
if(L >= R && b.L >= b.R)
return R > b.R;
return L < b.L;
}
}edg[maxn];
char ch[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i = 0 ; i < n ; i++)
{
scanf("%s",ch);
int l = 0 , r = 0 , all = 0;
for(int j = 0 ; j < strlen(ch) ; j++)
{
if(ch[j] == '(') r++;
else
{
if(r) r-- ,all++;
else l++;
}
}
edg[i].L = l,edg[i].R = r, edg[i].ALL = all;
}
sort(edg,edg+n);
int now = 0;
long long ans = 0 ;
for(int i = 0 ; i < n ; i++)
{
if(edg[i].L > now) edg[i].L = now;
ans += edg[i].L + edg[i].ALL;
now -= edg[i].L;
now += edg[i].R;
}
printf("%lld\n",ans*2);
}
}