2018 Multi-University Training Contest 1 hdu 6299 Balanced Sequence(貪心)
阿新 • • 發佈:2018-11-10
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=6299
題意:n個'('和 ')'和串,任意排列的拼接中最長的子序列,滿足括號匹配的最大長度
做法:把每個串做一個匹配,最後會有
1. 只包含’(’
2. 先是一串’)’然後再是一串’(’
3. 只包含’)’
我們只需要記一下第一種和第三種的總長度,對第二種進行排序(重點),把這一類放在中間,擇優選取即可
程式碼
#include<bits/stdc++.h> #define N 100005 #define P pair<int,int> using namespace std; typedef long long ll; const int M=1e9+7; const int inf=1e9+7; struct node{ int l,r; bool operator<(const node& a)const{ if(l-r>=0&&a.l-a.r>=0)return r>a.r; //左大於右,右少的先 if(l-r>=0)return 0; //左大於右的先 if(a.l-a.r>=0)return 1; return l<a.l; //左邊多的先 //優先佇列所以反著 } }; char s[N],sk[N]; int main() { int t,n; for(scanf("%d",&t);t;t--) { scanf("%d",&n); int ans=0; priority_queue<node>Q; int lsum=0,rsum=0; for(int i=0;i<n;i++){ scanf("%s",s); int m=strlen(s),top=0; for(int j=0;j<m;j++){ if(s[j]=='(')sk[top++]=s[j]; else if(top&&sk[top-1]=='(')top--,ans++; else sk[top++]=s[j]; } if(!top)continue; if(sk[0]=='('&&sk[top-1]=='(')lsum+=top; else if(sk[0]==')'&&sk[top-1]==')')rsum+=top; else { int k=0; while(sk[k]==')')k++; Q.push({top-k,k}); } } while(!Q.empty()){ int a=Q.top().l; int b=Q.top().r; Q.pop(); int k=min(b,lsum); lsum-=k; ans+=k; lsum+=a; } ans+=min(lsum,rsum); printf("%d\n",ans*2); } return 0; }