题意:
有n个字符串仅包含'('和')',n个字符串可以按随意的顺序排列,求最长的括号匹配子序列(可以不相连)的长度
思路:
对每个读入的字符串预处理,预处理出当前串内部无法消化掉的左括号数data[i].l和右括号数data[i].r
然后按以下排序规则排序:
friend bool operator< (const node &a , const node &b )
{
if ( a.l<=a.r&&b.l<=b.r )
return a.l>b.l;
else if ( a.l<=a.r&&b.l>b.r )
return false;
else if ( a.l>a.r&&b.l<=b.r )
return true;
else if ( a.l>a.r&&b.l >b.r )
return a.r<b.r;
}
贪心匹配
C++代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+5;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
struct node
{
int l,r;
friend bool operator< (const node &a , const node &b )
{
if ( a.l<=a.r&&b.l<=b.r )
return a.l>b.l;
else if ( a.l<=a.r&&b.l>b.r )
return false;
else if ( a.l>a.r&&b.l<=b.r )
return true;
else if ( a.l>a.r&&b.l >b.r )
return a.r<b.r;
}
}data[maxn];
char s[maxn];
int main()
{
for ( int T ; scanf ( "%d" , &T )==1 ; )
{
for ( int Cas=1 ; Cas<=T ; Cas++ )
{
int ans = 0,n;
scanf( "%d" , &n );
for ( int i=0 ; i<n ; i++ )
{
scanf ( "%s" , s );
data[i].l = 0;
data[i].r = 0;
int len = strlen(s);
for ( int j=0 ; j<len ; j++ )
if ( s[j]=='(' )
data[i].l++;
else
{
if ( data[i].l )
data[i].l--,ans++;
else
data[i].r++;
}
}
sort ( data , data+n );
int left = 0;
for ( int i=0 ; i<n ; i++ )
{
int tmp = min( left , data[i].r );
left -= tmp;
ans += tmp;
left += data[i].l;
}
printf ( "%d\n" , ans*2 );
}
}
return 0;
}