HDU6299.Balanced Sequence
这个题就是将括号处理一下,先把串里能匹配上的先计数去掉,然后统计左半边括号的前缀和以及右半边括号的前缀和,然后结构体排序,然后遍历一遍,贪心策略走一遍就可以了。
但是我写的时候排序写挫了,左(括号)多右(括号)少的和左少右多的,肯定左多的在前面,左少右多和左多右少的,肯定左多的在前面,左少右多和左少右多,谁的左边的多谁在前面,以及其他情况都按右少的前排,按这四种情况考虑就可以完美贪心了。只是可惜自己智障,其他就没什么了。
代码:
1 //1002-6299-贪心,前缀和,排序,使得匹配数量最多,排序写挫了,是真的菜 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<cstdlib> 7 #include<cassert> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 #include<cstdlib> 12 #include<cmath> 13 using namespace std; 14 typedef long long ll; 15 const int maxn=1e5+10; 16 const int inf=0x3f3f3f3f; 17 18 struct node{ 19 int l,r; 20 21 bool operator< (const node &a) const{ 22 if(l>r&&a.l<=a.r) return true;//左多右少 左少右多 23 if(l<=r&&a.l>a.r) return false;//左少右多 左多右少 24 if(l<=r&&a.l<=a.r) return l>a.l;//左少右多 左少右多 25 return r<a.r;//其他都按右边排 26 } 27 28 }a[maxn]; 29 30 char s[maxn]; 31 int main() 32 { 33 int t;scanf("%d",&t); 34 while(t--){ 35 int n;scanf("%d",&n); 36 for(int i=0;i<=n;i++) 37 a[i].l=a[i].r=0; 38 int ans=0; 39 for(int i=1;i<=n;i++){ 40 scanf("%s",s); 41 int len=strlen(s); 42 for(int j=0;j<len;j++){ 43 if(s[j]=='(') a[i].l++; 44 else{ 45 if(a[i].l>0) a[i].l--,ans++; 46 else a[i].r++; 47 } 48 } 49 } 50 sort(a+1,a+1+n); 51 int lsum=0; 52 for(int i=1;i<=n;i++){ 53 if(a[i].r<=lsum) ans+=a[i].r,lsum-=a[i].r; 54 else ans+=lsum,lsum=0; 55 lsum+=a[i].l; 56 } 57 printf("%d\n",ans*2); 58 } 59 return 0; 60 }