hdu 6299 Balanced Sequence(贪心)

题目

题意:给你n个括号字符串,排序这些括号字符串,怎么排序能使其配对最多,并输出总共有几个括号可以参与配对(配对成功的个数*2)。

      配对就是 ' ) ' 前面只要出现 ' ( ' 就可以配对,不一定要连续,不过一个括号不能重复使用哈

多校赛的时候没看这题,其实不知道自己多校赛后面都干嘛去了。。一直在浪费时间啊。。。虽然不知道如果自己做能不能看懂这题怎么做,听完题解再做的。。

思路:

1、首先每个字符串输入之后先预处理一下每个字符串,计算出每个字符串里自己本身可以配对几个,有几个' ( ' 和 ' ) ' 还没进行配对,这里用栈就可以实现了。

2、然后进行排序,排序的话遵守一个原则,就是他们自己谁能对形成配对的贡献大

  • 这个字符串里 ' ( ' 出现的次数比 ' ) ' 多,那么它就比较适合排左边(前面)
  • ' ) '比较多的话适合排在后面,这样能够使自己对整个配对做出的贡献最大
  • a和b比较的话,如果a和b ' ( ' 贡献相等时,谁的 ' ) ' 小就排前面,因为相对来说 ' ) ' 的要往后排,相对贡献会大一些

然后基本就是这样啦

AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 1e5+10;

struct Str{
    int l, r, num;  //l:(的数量  r: )的数量 num:匹配的数量
}str[maxn];

char s[maxn];

bool cmp(Str a, Str b){
    if(a.l > a.r)    //判断'('大于')'时,如果a,b都满足,则谁的')'小谁排前面,否则a排前面
        return b.l > b.r? a.r<b.r:true;
    return b.l <= b.r?a.l>b.l:false;
}

void init(int j){
    stack<char> S;
    int l = 0 ,r = 0, num = 0;
    for(int i = 0; s[i]!= '\0'; i++){
        if(s[i] == '('){
            S.push('(');
            l++;
        }
        else{
            if(!S.empty()){
                if(S.top() == '('){
                    S.pop();
                    num++;
                    l--;
                }
                else
                    r++;
            }
            else
                r++;
        }
    }
    str[j].l = l;
    str[j].r = r;
    str[j].num = num;
 //   printf("l = %d, r = %d, num = %d\n",l,r, num);
}

int main(){
    int ans = 0, t, n, i;
    scanf("%d",&t);
    while(t--){
        ans = 0;
        scanf("%d",&n);
        for(i = 1; i <= n; i++){
            scanf("%s",s);
            init(i);
            ans += str[i].num;
        }
        sort(str+1, str+1+n, cmp);
        int L = 0;
        for(i = 1; i <= n; i++){
            int temp = min(str[i].r,L);
            L += str[i].l -temp;
            ans += temp;
        }
        printf("%d\n",ans*2);
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值