题意:给定n个字符串,n的大小在1e5左右,字符串的长度也是1e5,字符串仅由‘(’或‘)’组成,合法串可以不是连续的,将这n个串按照一定的顺序排列起来,使得组合之后的字符串的合法串的长度最长。n*len的大小是1e6
思路:首先n*len的处理出来每一个字符串中合法的长度,处理的办法可以参考之前栈的想法,每遇见一个')',就判断前面‘(’的个数,只要不为0,此时就可以合成一个合法串,处理完之后可以得到剩下的‘)’和‘(’的个数,然后所有的n个串进行排序,最后将这些))((())((。。。。。))(((的串连接起来即可,排序的方式是)少(多的放在前面,反之放在后面,如果差不多的话,就根据))排序。
代码如下:
#include#include #include #include using namespace std;const int maxn = 100005;int t;int n;char s[maxn];struct NODE{ int l; int r; int sum; bool operator < (const NODE &b) const { if(l>=r && b.l<=b.r) return false; else if(l<=r && b.l>=b.r) return true; else if(l>=r && b.l>=b.r) return r>=b.r; else if(l<=r && b.l<=b.r) return l<=b.l; }} node[maxn];int main(){ scanf("%d", &t); while( t-- ) { scanf("%d", &n); for(int cnt=0; cnt 0) { node[cnt].r --; node[cnt].sum ++; } else { node[cnt].l++; } } else { node[cnt].r++; } } } sort(node, node+n); int ans; int now; ///now记录现在有多少个‘(’ ans = now = 0; for(int i=0; i =now) { ans += now; now = node[i].r; } else { ans += node[i].l; now -= node[i].l; now += node[i].r; } } printf("%d\n", ans*2); } return 0;}