题意:
t组测试数据,每组数据有 n 个只由 '(' 和 ')' 构成的括号串。
要求把这 n 个串排序然后组成一个大的括号串,使得能够匹配的括号数最多。
如()()答案能够匹配的括号数是 4,(()) 也是 4。
例如:
n = 2
)
)((
你可以将其排序为))((,数目为0,也可以将其排序为)((),数目为1。
解法:
贪心。
把所有字符串中本身能够匹配的括号全部去掉,然后剩下的字符串只有三种:
1、全是 '('
2、全是 ')'
3、一串 ')' 加一串 '('
对于每一种字符串,如果 '(' 的数目多于 ‘)’,就把它放在前面,按照字符串中的 ‘)’ 从小到大排序。
如果 ')' 的数目多于 ‘(’,就把它放在后面,按照字符串中的 ‘(’ 从大到小排序。
然后统计新串合法的括号数即可。
#include <iostream> #include <cstdio> #include <cstdlib> #include <string> #include <algorithm> using namespace std; #define maxn 100000 + 100 struct stringS { int x, y; }; bool cmp(stringS a, stringS b) { if (a.x <= a.y && b.x > b.y) return false; if (a.x > a.y && b.x <= b.y) return true; if (a.x <= a.y && b.x <= b.y) return a.x > b.x; if (a.x > a.y && b.x > b.y) return a.y < b.y; } int main() { int t; scanf("%d", &t); for (int ca = 1; ca <= t; ca++) { int n; scanf("%d", &n); stringS s[maxn]; int ans = 0; for (int i = 1; i <= n; i++) { char str[maxn]; scanf("%s", str); s[i].x = 0, s[i].y = 0; for (int j = 0; str[j] != '\0'; j++) if (str[j] == ')') { if (s[i].x) {s[i].x--; ans++;} else s[i].y++; } else s[i].x++; } sort(s+1, s+1+n, cmp); int instack = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= s[i].y; j++) if (instack) {instack--; ans++;} for (int j = 1; j <= s[i].x; j++) instack++; } printf("%d\n", ans * 2); } }