Balanced Sequence HDU - 6299(杭电多校1 B)

题目说要n个字符串串内随意组合以后将这些串放在一起,然后求最长的括号匹配的长度,并不要求是连续的

因为不需要是连续的,所以可以先把已经匹配好的括号加入到答案里面去,先把这些删掉,以为并不影响结果,然后最后就只剩下))))((((这些的序列,然后接下来对剩下的考虑

因为剩下的括号最多只有四种情况就是

1.只有(   ((((((((

2.只有)   )))))))

3.(比)多  (((((())

4.)比(多   ))))))(((

然后我们要做的就是把他们排序,既然要得到尽可能多的匹配,那就贪心去排序,每次将(放在前面,把)放在后面,然后排序规则可以这样

1.先把 ( 全放进来

2.把 ( 比 ) 多的串放在前面

3.如果两个串都是 ( 比 ) 多,那就把 ) 少的放在前面

4.如果两个都是 ( 比 ) 少,那就把 ( 多的放在前面

5.最后再把全部都是 ) 的放在后面。

然后在扫一遍,L记录我扫到这个串的时候还有多少 ( 没有匹配,然后每次尽可能多的拿去匹配掉.

#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define first fi
#define second se
#define lowbit(x) (x & (-x))

typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 100005;
const int maxm = 12;
using namespace std;

int n, m, tol, T;
struct Node {
    int l, r;
    Node () {
        l = r = 0;
    }
    bool operator < (Node a) const {
        if(r == 0)        return 1;
        if(a.r == 0)    return 0;
        if(l >= r && a.l < a.r)    return 1;
        if(l < r && a.l >= a.r)    return 0;
        if(l >= r && a.l >= a.r)    return r < a.r;
        else    return l > a.l;
    }
};
Node node[maxn];
char str[maxn];

void init() {
    memset(node, 0, sizeof node);
}

int main() {
    scanf("%d", &T);
    while(T--) {
        init();
        scanf("%d", &n);
        int ans = 0;
        for(int i=1; i<=n; i++) {
            stack<char> s;
            scanf("%s", str+1);
            int len = strlen(str+1);
            for(int i=1; i<=len; i++) {
                if(str[i] == '(')    s.push(str[i]);
                if(str[i] == ')') {
                    if(!s.empty() && s.top() == '(') {
                        ans+=2;
                        s.pop();
                    } else {
                        s.push(str[i]);
                    }
                }
            }
            while(!s.empty()) {
                char ch = s.top();
                if(ch == '(')    node[i].l++;
                else    node[i].r++;
                s.pop();
            }
        }
        sort(node+1, node+1+n);
        int L = 0;
        for(int i=1; i<=n; i++) {
            if(L >= node[i].r) {
                ans += 2*node[i].r;
                L -= node[i].r;
            } else {
                ans += 2*L;
                L = 0;
            }
            L += node[i].l;
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/H-Riven/p/9362296.html