HDU 6299 Balanced Sequence——贪心
原创
©著作权归作者所有:来自51CTO博客作者软糖酱八号机的原创作品,请联系作者获取转载授权,否则将追究法律责任
题意:
给定n个串,要求将这n个串按照一定的顺序拼接,使得最终串合法子序列长度之和最长
思路:
注意到每个串去掉所有匹配子串后剩下的一定是"))((("这种类似的形式,所以我们可以先预处理去掉每个串的匹配子串,顺便统计到结果里,剩下的部分就可以用两个数表示,我这里用l表示")"的数量,用r表示'('的数量,然后按照以下规则排序:
假定两个串s1, s2要比较顺序,则,
若s1.l >= s1.r && s2.l < s2.r, 那么s2在前s1在后
若s1.l < s1.r && s2.l >= s2.r,那么s1在前s2在后
若s1.l >= s1.r && s2.l >= s2.r,那么r大的在前
若s1.l < s1.r && s2.l < s2.r,那么l小的在前
这样排序后将所有串合并,然后统计最终序列的匹配子串的总长度即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
char s[maxn];
struct Data {
int l, r;
bool operator < (const Data &data) {
if (l >= r && data.l < data.r) {
return false;
}
else if (l < r && data.l >= data.r) {
return true;
}
else if (l >= r && data.l >= data.r) {
return r > data.r;
}
else {
return l < data.l;
}
}
}a[maxn];
void solve() {
int n;
scanf("%d", &n);
int ans = 0;
for (int i = 1; i <= n; i++) {
scanf("%s", s + 1);
a[i].l = a[i].r = 0;
for (int j = 1; s[j] != 0; j++) {
if (s[j] == '(') {
a[i].r++;
}
else {
if (a[i].r != 0) {
a[i].r--;
ans++;
}
else {
a[i].l++;
}
}
}
}
sort(a + 1, a + 1 + n);
int r = 0;
for (int i = 1; i <= n; i++) {
int temp = min(r, a[i].l);
r = r - temp;
ans += temp;
r += a[i].r;
}
printf("%d\n", ans * 2);
}
int main() {
int T;
scanf("%d", &T);
for (int i = 1; i <= T; i++) {
solve();
}
return 0;
}