zoukankan      html  css  js  c++  java
  • HDU

    题目链接

    题意:

    给定 $n$ 个括号序列,问任意组合之后最大的匹配长度是多少。

    思路:

    要使得匹配长度最大,那么就是尽可能多的匹配括号,那么我们就可以记录每一个序列本身不能够匹配的左括号数和右括号数;

    然后对于两个序列之间,我们分情况讨论,然后排序一遍,再进行匹配一次,记录答案就好了,详情见代码注释。

     1 /*
     2 * @Author: windystreet
     3 * @Date:   2018-08-07 08:46:12
     4 * @Last Modified by:   windystreet
     5 * @Last Modified time: 2018-08-07 09:03:00
     6 */
     7 #include<bits/stdc++.h>
     8 
     9 using namespace std;
    10 
    11 #define X first
    12 #define Y second
    13 #define eps  1e-5
    14 #define gcd __gcd
    15 #define pb push_back
    16 #define PI acos(-1.0)
    17 #define lowbit(x) (x)&(-x)
    18 #define bug printf("!!!!!
    ");
    19 #define mem(x,y) memset(x,y,sizeof(x))
    20 
    21 typedef long long LL;
    22 typedef long double LD;
    23 typedef pair<int,int> pii;
    24 typedef unsigned long long uLL;
    25 
    26 const int maxn = 1e5+2;
    27 const int INF  = 1<<30;
    28 const int mod  = 1e9+7;
    29 
    30 struct node
    31 {
    32     int p,q;        // 左括号,右括号
    33 }s[maxn];
    34 
    35 bool cmp(node a, node b){
    36     if(a.q >= a.p && b.q < b.p)return false;         // 当a的右括号数大于左括号数 且 b的左括号数大于右括号数,则将b排在前面
    37     if(b.q >= b.p && a.q < a.p)return true;          // 当a的左括号数大于右括号数 且 b的右括号数大于左括号数,则将a排在前面
    38     if(a.q >= a.p && b.q >= b.p) return a.p >b.p;    // 当a,b的右括号都大于左括号的时候,就将左括号多的排前面
    39     return a.q<b.q;                                  // 否则的话还是将左括号多的排前面
    40 }
    41 
    42 char str[maxn];
    43 
    44 void solve(){
    45     int n,ans = 0;
    46     scanf("%d",&n);
    47     for(int i=1;i<=n;i++){
    48         scanf("%s",str);                            
    49         s[i].p = s[i].q = 0;
    50         int len = strlen(str);
    51         for(int j=0;j<len;j++){
    52             if(str[j]== '(')s[i].p++;                // 记录左括号
    53             if(str[j]== ')'){    
    54                 if(s[i].p){                          // 先行在序列中匹配
    55                     s[i].p--;ans+=2;
    56                 }else s[i].q++;                      // 不能匹配的话就记录右括号
    57             }
    58         }
    59     }
    60     sort(s+1,s+1+n,cmp);                            
    61     int cnt = 0;                                    // 记录当前未匹配的左括号的数量
    62     for(int i=1;i<=n;i++){
    63         if(s[i].q > cnt) s[i].q = cnt;                
    64         ans += s[i].q*2;                            // 更新当前可以匹配的答案
    65         cnt -= s[i].q;                    
    66         cnt += s[i].p;
    67     }
    68     printf("%d
    ",ans);
    69     return;
    70 }
    71 
    72 int main()
    73 {
    74 //    freopen("in.txt","r",stdin);
    75 //    freopen("out.txt","w",stdout);
    76 //    ios::sync_with_stdio(false);
    77     int t = 1;
    78     scanf("%d",&t);
    79     while(t--){
    80     //    printf("Case %d: ",cas++);
    81         solve();
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    HDU2222 自动机(学习中)
    POJ 2289(多重匹配+二分)
    POJ 1486二分图的必要边
    二分图
    2015陕西 并查集
    Hdu2680 最短路
    函数调用约定
    用01随机函数构造[a,b]整数范围随机数
    hello
    Ubuntu 16.04 install R language
  • 原文地址:https://www.cnblogs.com/windystreet/p/9435098.html
Copyright © 2011-2022 走看看