Balanced Sequence HDU - 6299 (字符串,括号匹配, 贪心)

Balanced Sequence

 题目链接:HDU - 6299 

题意: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;
}

猜你喜欢

转载自blog.csdn.net/sirius_han/article/details/81196072