zoukankan      html  css  js  c++  java
  • HDU

    题意:给你n个只含'(' ')'的字符串, 你可以将这些字符串左右端随意连接成一个新串,然后求出能得到的符合条件的 最长子序列。
    条件:(1) 空串符合 (2) 如果A符合则 (A)也符合 (3)如果A,B符合则 AB也符合 : 总言之就是将这个括号串放入栈中,如果能够全部弹出则为符合条件的串(左右括号匹配就弹出)
    思路:关于这道题,一开始可能不会想到贪心。(读题都读到自闭..)但是后面会发现要使子序列最长,我们肯定希望在某个串中最近的两个左右括号匹配
    比如  ) ( ( ) ( ( ) ,我们肯定希望2与4匹配而不是与7匹配, 即只要在串中右两个匹配即把它算到最长子序列的串中。

    这样以来我们取完这匹配好的括号后就只剩  ) ( (  , 上面样例字符串。即任何一个字符串匹配完最后会出现左右括号剩余(或者没有)的情况

    接下来就是讨论像多个串有 ) (  这种形式如何最大匹配。首先按照贪心的想法,我们肯定要让两个串左右两边尽可能接近这样不会浪费括号。

    当我们匹配相邻的两个串时,比如 a: )))(  b:)((  ,我们会找左右括号哪边更大:a的右括号数大于左括号,b的左括号数大于右括号,所以大大匹配,这两个就要交换位置

    如果 a:)))((   b:))( 两边都是右括号小于左括号,则我们希望两个串左括号或者右括号数目更多的进行匹配。 当然反之同理(就是右括号比左括号多的情况)

    所以这样我们就得到了贪心的排序:

     if(a.l > a.r) return b.l > b.r? a.r < b.r : true;
     if(a.l <= a.r) return b.l <= b.r? a.l > b.l :  false;

    code:

    #include <cstring>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <string>
    using namespace std;
    const int maxn = 1e5+10;
    struct node{
        int l,r;
    }p[maxn];
    bool cmp(node a,node b){
        if(a.l > a.r) return b.l > b.r? a.r < b.r : true;
        if(a.l <= a.r) return b.l <= b.r? a.l > b.l :  false;
    }
    char s[maxn];
    int main(){
        int n;
        int T;
        scanf("%d",&T);
        while(T--){
           scanf("%d",&n);
           int ans = 0;
           for(int i = 1;i <= n;i++){
                scanf("%s",s);
                int len = strlen(s);
                p[i].l = p[i].r = 0;
                for(int j = 0;j < len;j++){
                    if(s[j] == '(') p[i].l++;
                    else{
                        if(p[i].l > 0){
                            p[i].l--;
                            ans += 1;
                        }
                        else{
                            p[i].r++;
                        }
                    }
                }
           }
            sort(p+1,p+n+1,cmp);
            int l=0;
            for(int i=1; i<=n; i++)
            {
                if(p[i].r<=l)
                    ans+=p[i].r,l-=p[i].r;
                else ans+=l,l=0;
                l += p[i].l;
            }
            printf("%d
    ",ans*2);
        }
        return 0;
    }
  • 相关阅读:
    软件构造—— 实验二 lex词法分析
    软件构造-实验1 根据状态转换图手工构造词法扫描器
    PHP——实验四 PHP操作数据库
    判断是不是素数
    hexo和github pages的关系
    Python的map,reduce,filter函数
    CentOS源码更新Linux最新内核
    CentOS打Meltdown等漏洞的补丁包
    let申明与const申明
    正则表达式
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11356784.html
Copyright © 2011-2022 走看看