HDU 6299-Balanced Sequence(貪心)

大白QQly成長日記發表於2018-09-01

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;
}

 

相關文章