Balanced Sequence
题意:n个只包含左右括号的字符串,问如何连接这些字符串可以使得匹配到的括号最多;
思路:先把没个字符串自身能匹配的括号去掉,则剩的一定有p个右括号+q个左括号组成;形如))))))((((;
要想匹配到的括号最多,则尽量让每个括号都起作用了;
如果只包含左括号则把他放在最前边,如果只有右括号把他放在最后边;
可以看出左括号多于右括号的在前,反之在后;
同是左括号多于右括号的,右括号少的在前;
同是右括号多于左括号的,左括号少的在后;
这里我的代码是倒着排的,所以最后计算是倒着匹配;
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node{
int l, r;
}p[maxn];
char s[maxn], sta[maxn];
int ans;
bool cmp(node a, node b){
if(a.l<=a.r&&b.l>b.r) return true;
if(a.l>a.r&&b.l<=b.r) return false;
if(a.r>=a.l&&b.r>=b.l) return a.l<b.l;
return a.r>b.r;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
ans=0;
for(int i=1; i<=n; i++){
scanf("%s", s);
p[i].l=p[i].r=0;
int len=strlen(s);
for(int j=0; j<len; j++){
if(s[j]=='(') p[i].l++;
else{
if(p[i].l) ans++, p[i].l--;
else p[i].r++;
}
}
}
sort(p+1, p+1+n, cmp);
int cnt=0;
for(int i=2; i<=n; i++){
cnt+=p[i-1].r;
if(p[i].l>cnt){
ans+=cnt;
cnt=0;
}
else{
ans+=p[i].l;
cnt-=p[i].l;
}
}
printf("%d\n", ans*2);
}
return 0;
}