您的位置:首页 > 其它

bzoj4922 Karp-de-Chant Number 动态规划+贪心

2017-07-10 07:53 381 查看
题意:给你n个括号序列,让你尽量选出多的括号序列,使得最终的总序列加起来刚好为一个合法序列。

套路大集合

算出每个括号序列的前缀和,然后就是bzoj3709:

y>x的和y

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
using namespace std;
#define N 310
#define MAXM 1010
#define ll long long
#define INF 1000000000
struct node{
int x,y,len;
}a
,b
;
int n;
char s
;
int f
[N*N];

int tot1,tot2;
int ans;
bool cmp1(const node &x,const node &y){
return x.x<y.x;
}
bool cmp2(const node &x,const node &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);
}
//printf("%d\n",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
[0]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: