Chiaki has n strings s1,s2,…,sn consisting of '(' and ')'. A string of this type is said to be balanced:
+ if it is the empty string
+ if A and B are balanced, AB is balanced,
+ if A is balanced, (A) is balanced.
Chiaki can reorder the strings and then concatenate them get a new string t . Let f(t) be the length of the longest balanced subsequence (not necessary continuous) of t . Chiaki would like to know the maximum value of f(t) for all possible t .
Input
There are multiple test cases. The first line of input contains an integer T , indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤105 ) -- the number of strings.
Each of the next n lines contains a string si (1≤|si|≤105 ) consisting of `(' and `)'.
It is guaranteed that the sum of all |si| does not exceeds 5×106 .
Output
For each test case, output an integer denoting the answer.
Sample Input
2
1
)()(()(
2
)
)(
Sample Output
4
2
题目大意:每个样例给出n个串,n个串能够自由组合,要求输出最大的符合数。例如:)()(()(,有2组(),所以输出4,样例2:2个串组合成)(),有一组(),所以输出2。
思路:不改变串,所以先提取出每个串中原有的符合数,再进行组合,除去后剩余的就只有四种情况,((((全左,))))全右,))(((左大于右,)))((右大于左。相等的情况可以不用考虑。对这4种进行排列获得最大组合数,那就一定是左边多的放在最前面,右边多的放在最后面即可。
注意:重载运算符的条件需要考虑清楚。
......本来我用栈写的结果T无数发,还以为这题卡容器,结果网上有大佬用栈过了......还木有找出问题。
模拟栈ac代码:
#include<set>
#include<map>
#include<list>
#include<deque>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<stdio.h>
#include<sstream>
#include<stdlib.h>
#include<string.h>
//#include<ext/rope>
#include<iostream>
#include<algorithm>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define per(i,a,b) for(int i=a;i<=b;++i)
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define LL long long
#define swap(a,b) {int t=a;a=b;b=t}
using namespace std;
//using namespace __gnu_cxx;
struct node{
int x;
int y;
}p[100005];
int cmp(const node &a,const node &b)
{
if(a.y>=a.x&&b.y<b.x) return 0;//边界情况
if(a.y<a.x&&b.y>=b.x) return 1;//边界情况
if(a.y<a.x&&b.y<b.x) return a.y<b.y;
else return a.x>b.x;
}//对应4种情况的排列
int main()
{
int t,n,k;
scanf("%d",&t);
while(t--)
{
k=0;
memset(p,0,sizeof(p));
string s;
scanf("%d",&n);
per(i,0,n-1){
cin>>s;
per(j,0,s.size()-1){
if(s[j]==')')
{
if(p[i].x<=0) p[i].y++;
else p[i].x--,k++;
}
if(s[j]=='(') p[i].x++;
}
}
sort(p,p+n,cmp);
int l=0;
per(i,0,n-1){
if(p[i].y<=l){
k+=p[i].y;
l-=p[i].y;
}else{
k+=l;l=0;
}
l+=p[i].x;
}
cout<<k*2<<endl;
}
return 0;
}
自己写的不知道哪儿错的栈代码:(T)
#include<set>
#include<map>
#include<list>
#include<deque>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<vector>
#include<stdio.h>
#include<sstream>
#include<stdlib.h>
#include<string.h>
//#include<ext/rope>
#include<iostream>
#include<algorithm>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define per(i,a,b) for(int i=a;i<=b;++i)
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define LL long long
#define swap(a,b) {int t=a;a=b;b=t}
using namespace std;
//using namespace __gnu_cxx;
struct node{
int x;
int y;
}p[100005];
int cmp(const node &a,const node &b)
{
if(a.y==0) return 1;
if(b.y==0) return 0;
if(a.x>=a.y&&b.x<b.y) return 1;
if(a.x>=a.y&&b.x<b.y) return 0;
if(a.x>=a.y&&b.x>=b.y) return a.y<=b.y;
return a.x>=b.x;
}
int main()
{
int t,n,k;
scanf("%d",&t);
while(t--)
{
k=0;
memset(p,0,sizeof(p));
stack<char>q;
string s;
scanf("%d",&n);
per(i,1,n){
cin>>s;
per(j,0,s.size()-1){
if(s[j]=='(') q.push(s[j]);
if(s[j]==')')
{
if(!q.empty()&&q.top()=='(') k++,q.pop();
else q.push(s[j]);
}
}
while(!q.empty())
{
if(q.top()=='(') p[i].x++;
else if(q.top()==')') p[i].y++;
q.pop();
}
}
sort(p+1,p+n+1,cmp);
int l=0;
per(i,1,n){
if(p[i].y<=l){
k+=p[i].y;
l-=p[i].y;
}else{
k+=l;l=0;
}
l+=p[i].x;
}
cout<<k*2<<endl;
}
return 0;
}