- B - Balanced Sequence
- HDU - 6299
- 题意:给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; }
B - Balanced Sequence HDU - 6299 -贪心+思维
最新推荐文章于 2019-07-17 09:14:51 发布