hdu 6299 Balanced Sequence(模拟栈, 贪心)

Chiaki has n strings s1,s2,…,sn consisting of ‘(’ and ‘)’. A string of this type is said to be balanced:

  • if it is the empty string
  • if A and B are balanced, AB is balanced,
  • if A is balanced, (A) is balanced.

Chiaki can reorder the strings and then concatenate them get a new string t. Let f(t) be the length of the longest balanced subsequence (not necessary continuous) of t. Chiaki would like to know the maximum value of f(t) for all possible t
.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤105) – the number of strings.
Each of the next n lines contains a string si (1≤|si|≤105) consisting of (' and)’.
It is guaranteed that the sum of all |si| does not exceeds 5×106
.
Output
For each test case, output an integer denoting the answer.
Sample Input

2
1
)()(()(
2
)
)(

Sample Output

4
2

题意想必大家都理解,我就不多说了,,,

题的关键在于当左右括号匹配时,将已匹配的括号从数组中删除,并且数量+2(看到这,是不是觉得和栈很像~),最后将每个字符串剩余部分进行组合,达到匹配的括号最大化就可,比赛时我就卡在了这,主要是时间不多了,最后40分钟才开始看,,,

本来开始时我是直接用的栈,但我开始时没想到如何建立栈组,,,不知怎么标记该栈左右剩余的个数及情况,,,emmm后来发现自己想多了,,,其实很简单,只需再开一个数组,建立一个结构体,记录一下左右括号数就行,,,

主要是因为建立结构体后,我就否定了上面的栈, 感觉重新模拟似乎更方便,就干脆直接都是模拟了

不过有一个地方我觉得我没问题,但就是wa,我也不知为何,,,十分难受,,,wa的代码在本篇的最后,有哪位好心的大佬能帮帮我这个小渣渣嘛~

#include<cstdio>
#include<stack>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

#define clr(x) memset(x, 0, sizeof(x));
const int N = 1000010;
typedef long long ll;

struct node{
    int l, r, s;//分别代表左括号,右括号及该字符串最长平衡子串的长度
}a[N], b;

bool cmp(node x, node y){
    if(x.l > x.r && y.r >= y.l)   return 1;
    else if(x.l <= x.r && y.r < y.l)    return 0;
    else if(x.l > x.r && y.l > y.r)     return x.r < y.r;
    else return x.l > y.l;

}

int main(){
    int t, n;
    char c[N];
    scanf("%d", &t);
    while(t--){
        scanf("%d", &n);
        for(int i=0; i<n; i++){
            scanf("%s", c);
            //cout << i << ' ' <<c[i] << endl;
            int len = strlen(c);
            a[i].l = a[i].r = a[i].s = 0;
            for(int j = 0; j < len; j++){
                if(c[j] == '('){
                    a[i].l++;
                }
                else{
                    if(a[i].l > 0){
                        a[i].s += 2;
                        a[i].l--;
                    }
                    else{
                        a[i].r++;
                    }
                }
            }
            //cout << "a " << i << ' ' <<a.top() << endl;
        }
        sort(a, a+n, cmp);
        int l = 0, sum = 0;
        for(int i = 0; i < n; i++){
            sum += a[i].s;
            int r = a[i].r;
            if(l && r){
                int m = min(l, r);
                sum += 2*m;
                l-=m;
            }
            l += a[i].l;
        }
        printf("%d\n", sum);
    }
    //system("pause");
    return 0;
}

哪位大佬能帮忙解释一下 我这个判断为什么不对~哇~难受~qwq

 b.s = b.l = b.r = 0;
 for(int i = 0; i < n; i++){
    b.s += a[i].s;
           b.l += a[i].l;
    b.r += a[i].r;
}
 b.l -= a[n-1].l;
 b.r -= a[0].r;
// cout << b.l << ' ' << b.r << endl;
int m = min(b.l, b.r);
// cout << m << endl;
b.s += 2*m;

猜你喜欢

转载自blog.csdn.net/ling_wang/article/details/81325198