這題真是tmd……讓我想起了做bohater時候的絕望
還好最後A了
注意到每個括弧序列相當於必須在當前首碼和>=x的情況下才能選,選完之後首碼和會+y
那麼就是bohater原題了,按那道題的順序排序一下,然後DP即可,f[i][j]表示只用前i個串首碼和為0的最長長度
答案為f[n][0]
#include<iostream>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<cstdlib>#include<cstdio>#include<map>#include<bitset>#include<set>#include<stack>#include<vector>#include<queue>using namespace std;#define MAXN 310#define MAXM 1010#define ll long long#define eps 1e-8#define MOD 1000000007#define INF 1000000000struct data{int x;int y;int len;};int n;char s[MAXN];int f[MAXN][MAXN*MAXN];data a[MAXN];data b[MAXN];int tot1,tot2;int ans;bool cmp1(const data &x,const data &y){return x.x<y.x;}bool cmp2(const data &x,const data &y){return x.x+x.y>y.x+y.y;}int main(){int i,j;scanf("%d",&n);for(i=1;i<=n;i++){scanf("%s",s+1);a[i].x=0;int now=0;for(j=1;s[j];j++){now+=s[j]=='('?1:-1;a[i].x=max(a[i].x,-now);}a[i].len=j-1;a[i].y=now;}for(i=1;i<=n;i++){if(a[i].y>=0){a[++tot1]=a[i];}else{b[++tot2]=a[i];}}if(tot1){sort(a+1,a+tot1+1,cmp1);}if(tot2){sort(b+1,b+tot2+1,cmp2);}memset(f,0xef,sizeof(f));f[0][0]=0;for(i=1;i<=tot2;i++){a[tot1+i]=b[i];}int s=0;for(i=1;i<=n;i++){for(j=0;j<=s;j++){f[i][j]=f[i-1][j];}for(j=a[i].x;j<=s;j++){f[i][j+a[i].y]=max(f[i][j+a[i].y],f[i-1][j]+a[i].len);}s+=a[i].len;}printf("%d\n",f[n][0]);return 0;}/**/