Balanced Sequence

题目链接:https://vjudge.net/contest/364422#problem/B

题目大意:

我们有N个字符串,我们要让更多的“(”与“)”匹配起来,问最大的匹配数是多少?

想法:

我们首先先把字符串里面可以配对的先配对完,然后剩下的形式肯定是 x 个 ) + y 个 ( ,然后我们对于这种形式进行分类讨论(也就是对x > y 还是 y > x)去讨论,对于不同的情况最大的配对的情况显然是不一样的。我们维护这样的一个类似于优先队列的东西,然后就可以直接直接配对了。具体的还是看代码吧
#pragma GCC optimize(3,"Ofast","inline")//O3优化
#pragma GCC optimize(2)//O2优化
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)

const double eps = 1e-10;
const int maxn = 2e4 + 10;
const int mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct Node
{
    int x, y;
}in[maxn];

char s[maxn];

bool cmp(Node a, Node b)
{
    //.x表示未匹配'('的数量,.y表示未匹配')'的数量
    if(a.x > a.y){    // 如果 ( 比 ) 多
        if(b.x > b.y) {  // ( 比 ) 多,那么肯定把 ) 从小往大排
            return a.y < b.y;
        }
        else{  // 如果 b 是 ) 比 ( 多 ,那么肯定a在前b在后,不交换位置
            return 1;
        }
    }
    else { // 如果 ) 比 ( 多
        if(b.x > b.y){  // 如果 b 是 ( 比 ) 多,那么肯定b在前a在后,交换位置
            return 0;
        }
        else { // ) 比 ( 多,那么肯定 ( 从大往小排
            return a.x > b.x;
        }
    }
}

int main()
{
    int T;
    scanf("%d", &T);
    getchar();
    while(T--){
        int n;
        scanf("%d", &n);
        getchar();
        int ans = 0, len;
        for(int i = 0; i < n; i++){
            scanf("%s", s);
            getchar();
            in[i].x = 0, in[i].y = 0;
            len = strlen(s);
            for(int j = 0; j < len; j++){
                if(s[j] == '('){
                    in[i].x++;
                }
                else if(s[j] == ')'){
                    in[i].y++;
                    if(in[i].x > 0){
                        in[i].x--;
                        in[i].y--;
                        ans++;
                    }
                }
            }
        }
        /*
        printf("ans = %d
", ans);
        for(register int i = 0; i < n; i++){
            printf("i = %d x = %d y = %d
", i, in[i].x, in[i].y);
        }
        */
        sort(in, in + n, cmp);
        int x = in[0].x;
        for(int i = 1; i < n; i++){
            if(x > 0 && in[i].y > 0){
                int t = min(x, in[i].y);
                x -= t;
                ans += t;
            }
            x += in[i].x;
        }
        printf("%d
", ans * 2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-Ackerman/p/12616968.html