【题目链接】
http://acm.hdu.edu.cn/showproblem.php?pid=6299
题目意思
给你n个‘(’‘)’组成的字符串,“()”算平衡,现在问你将n个字符串重新组合,能达到的最大平衡值。一个“()”算2.
解题思路
一个字符串括号用栈来模拟,遇到‘(’压人栈,遇到‘)’如果栈中有‘(’则弹出(‘(’注定在栈的最顶端)。每个字符串都这么处理后剩下都为“))))(((((((”结构的括号串。现在就判断这么组合会多消了。首先不能发现如果‘(’多于‘)’应该放前面,这样消除后剩的为‘)’个数少于放后面剩‘(’。同理相反的放前面。接着就是同在前面的应该用‘)’的排,少的放前面这样剩的就少。同在后面的用‘(’排,少的放后面。
代码部分
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
#include <math.h>
#include <set>
using namespace std;
#define LL long long
#define inf 0x3f3f3f3
const int mod = 1e9+7;
const int N = 1e5+7;
struct node
{
int l,r,ans;
}a[N];
bool cmp (node x,node y)
{
///')'比'('多的放后面
if (x.r >= x.l && y.r < y.l)
return false;
if (x.r < x.l && y.r >= y.l)
return true;
///')'比'('少 比较')'少的放前面
/// ')'比'('多 比较'('少的放后面
if (x.r < x.l && y.r < y.l)
return x.r<y.r;
else return x.l>y.l;
}
int main()
{
int t;
char str[N];
scanf("%d",&t);
while (t--)
{
int n;
scanf("%d",&n);
for (int i = 0; i < n; i++)
{
scanf("%s",str);
int len = strlen(str);
a[i].l = a[i].r = a[i].ans = 0;
for (int j = 0; j < len; j++)
{
if (str[j] == '(')
a[i].l++;
else
{
if (a[i].l > 0)
{
a[i].l--;
a[i].ans++;
}
else a[i].r++;
}
}
}
sort(a,a+n,cmp);
for (int i = 0; i < n ; i++)
printf("%d %d %d\n",a[i].l,a[i].r,a[i].ans);
int ans = 0,now = 0; ///now代表剩余的'('
for (int i = 0; i < n; i++)
{
if (a[i].r > now)
{
a[i].ans += now;
now = 0;
}
else
{
a[i].ans += a[i].r;
now -= a[i].r;
}
ans += a[i].ans;
now += a[i].l;
}
printf("%d\n",ans*2);
}
return 0;
}