HDU 6299 Balanced Sequence(流水線排程貪心)
阿新 • • 發佈:2018-12-24
題意
給出 個只包含左右括號的字串,將這些字串拼起來,要求最終拼出來的括號序列中,最長的完全匹配括號子序列的長度最長,問最長子序列長度。
輸入
第一行為一個整數 ,接下去有 組資料,每組資料第一行為一個整數 ,後面 行每行為一個只包含左右括號的字串 ,資料保證 的和不超過 。
輸出
輸出最長完全匹配子序列長度。
樣例
輸入 |
---|
2 1 )()(()( 2 ) )( |
輸出 |
4 2 |
題解
可以發現,每個字串中,已經匹配的左右括號,不論以任何順序與其他字串連線,這些已經匹配的左右括號對都不會改變,用棧模擬匹配後,最後只會剩下最前面的 個
)
和最後面的 個(
,類似)))((
的形式,只有這些括號在和其他字串匹配的時候才會產生新的括號匹配子序列。
如果字串 有 個)
和 個(
,字串 有 個)
和 個(
,將 放在 的前面(不必相鄰),則會產生 對新的括號匹配子序列,將 放在 的前面,則會產生 對新的括號匹配子序列,現在貪心地對所有字串進行排序,如果 ,則把 排在 的前面,如果 大,則把 排在 的前面,如果 ,則把含有(
個數多的放在前面,最後掃一遍整個排序拼接後的字串,就可以計得到答案。
過題程式碼
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 100000 + 100;
struct Node {
int l, m, r;
Node() {
l = m = r = 0;
}
Node(int L, int M, int R) {
l = L;
m = M;
r = R;
}
};
bool operator<(const Node &a, const Node &b) {
int aa = min(a.r, b.l);
int bb = min(b.r, a.l);
if(aa == bb) {
return a.r > b.r;
}
return aa > bb;
}
int T, n;
char str[maxn];
Node node[maxn];
Node Get() {
int len = strlen(str + 1);
Node ret;
ret.l = ret.r = 0;
for(int i = 1; i <= len; ++i) {
if(str[i] == ')') {
if(ret.r != 0) {
--ret.r;
} else {
++ret.l;
}
} else {
++ret.r;
}
}
ret.m = len - ret.l - ret.r;
return ret;
}
int main() {
#ifdef Dmaxiya
freopen("test.txt", "r", stdin);
#endif // Dmaxiya
ios::sync_with_stdio(false);
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%s", str + 1);
node[i] = Get();
}
sort(node, node + n);
Node tmp = node[0];
Node ll = node[0];
Node rr;
for(int i = 1; i < n; ++i) {
rr = node[i];
tmp.l = rr.l + ll.l - min(ll.r, rr.l);
tmp.r = ll.r + rr.r - min(ll.r, rr.l);
tmp.m = ll.m + rr.m + 2 * min(ll.r, rr.l);
ll = tmp;
}
printf("%d\n", tmp.m);
}
return 0;
}