题意:给出一些字符串,重新组合,使括号的匹配数量最多
这道题场上没能出,当时看了一眼,关于括号的,以为是个dp,就没有再去做这道题。
这道题事实上是个贪心,先把已经匹配好的括号数量统计出来。剩下的括号往两边堆,右括号往左边堆,左括号往右边堆。然后就是排序。
左括号比右括号多的这种情况肯定要排在右括号比左括号多的前面。
左括号都比右括号多时,就按照右括号少的在前面
右括号都比左括号多时,就按照左括号多的在前面
仔细想一下,确实是这样才能使匹配数量最大化。
看dls直播讲题的时候有人说流水调度问题,仔细想一下,好像确实是这样。算法课没有好好学QAQ,学习了一下dls的代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 1e5+10;
struct node
{
int l,r,add;
bool operator<(const node& s)const
{
if(l<=r&&s.l>s.r)
return false;
if(l>r&&s.l<=s.r)
return true;
if(l<=r&&s.l<=s.r)
return l>s.l;
return r<s.r;
}
}a[maxn];
char s[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
a[i].l = a[i].r = a[i].add = 0;
scanf("%s",s);
int len = strlen(s);
for(int j = 0; j < len; j++)
{
if(s[j]=='(')
{
a[i].l++;
}
else
{
if(a[i].l>0)
{
a[i].l--;
a[i].add++;
}
else
a[i].r++;
}
}
}
sort(a+1,a+n+1);
int now = 0;
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(a[i].r>now)
a[i].r = now;
ans += a[i].r+a[i].add;
now -= a[i].r;
now += a[i].l;
}
printf("%d\n",ans*2);
}
return 0;
}