Balanced Sequence HDU
阿新 • • 發佈:2018-12-20
- 題意:給n個括號字串,reorder改變這n個字串的位置,讓最終匹配的括號數最大
- 思路:先預處理出原來每個串中匹配的個數,因為無論怎麼動都不會改變它們。
- 所以結構體記錄每個串中已經匹配的數目,不匹配的‘)‘個數為R,不匹配的’(‘個數為L
- 接下來就是處理這些沒有匹配的讓它們儘可能多的湊出匹配的來,先分一下情況:
- 1. 只包含’(’ 2. 前面是’)’後面是’(’ .3. 只包含’)’ ,然後,按照第一類,第二類,第三類的順序放置
- 重構排序函式:
-
if(a.l>a.r&&b.l>b.r) return a.r<b.r; if(a.l>a.r)return 1; return b.l<=b.r?a.l>b.l:0;
- 第一優先順序:如果 a與b的 ‘(’數目都大於’)‘數目,那麼它們就需要按照’)‘數目小的在前面
- 這就包含了上面三類中的第一類與第二類中的 ‘(’數目大於’)‘的部分
- 第二優先順序為:如果a是一二類中的b是第三類的直接返回1,就是返回a在前面
- 第三優先順序為:經歷了前兩級說明a一定是第三類或第二類中 ‘(’數目小於’)‘的了,
- 但是b不確定,判斷如果b是第二類‘(’數目都大於’)‘直接返回0也就是返回b在前面
- 如果b是第二類中 ‘(’數目小於’)‘的那麼需要與a比較’(‘大的在前面。
- 然後在模擬一遍括號棧模擬操作求一下個數
-
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 125050 char str[maxn]; int n,t,ans,sum; struct node { int l,r,s; } num[maxn]; bool cmp(node a,node b) { if(a.l>a.r&&b.l>b.r) return a.r<b.r; if(a.l>a.r)return 1; return b.l<=b.r?a.l>b.l:0; } void solve(int orz,int len) { num[orz].l=num[orz].r=0; stack<char>qyn; for(int i=0; i<len; i++) { if(!qyn.empty()) { if(qyn.top()=='('&&str[i]==')') qyn.pop(); else qyn.push(str[i]); } else qyn.push(str[i]); } while(!qyn.empty()) { if(qyn.top()==')') num[orz].r++; else num[orz].l++; qyn.pop(); } num[orz].s=len-num[orz].l-num[orz].r; } int main() { scanf("%d",&t); while(t--) { sum=ans=0; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%s",str); int len=strlen(str); solve(i,len); } sort(num,num+n,cmp); stack<char>stk; while(!stk.empty())stk.pop(); for(int i=0; i<n; i++) { sum+=num[i].l+num[i].r; while(num[i].r--) { if(!stk.empty()) { if(stk.top()=='(') stk.pop(); else stk.push(')'); } else stk.push(')'); } while(num[i].l--) stk.push('('); ans+=num[i].s; } ans+=(sum-stk.size()); printf("%d\n",ans); } return 0; }