题意:给定 $n$ 个括号序,让你从中选取一些括号序按照任意顺序拼接,最终生成一个合法的括号序列,求这个合法序列长度最大值.

题解:假设括号序列相对顺序固定,而我们要做的只是判断选还是不选的话可以转化为一个简单的背包问题:

令 $f[i][j]$ 表示考虑前 $i$ 个括号序,左括号比右括号多 $j$ 个的最长长度.

转移为:$f[i][j]=max(f[i][j],f[i-1][j-k]+len[i])$ 其中 $k$ 表示当前序列 $i$ 中右括号比左括号多的个数.

转移的时候让 $j>=0$,这样就不会出现不合法的情况了.

但是,我们要给序列设计一个顺序,这也是本题的难点.

但是,可以看出这个和之前一道贪心题挺像的.

初始血量为 $0$,右括号减血,左括号加血,让你设计一种排序方式使得尽可能拿更多的序列.

那么,显然要将能回血的且右括号更小的放到前面,然后对于不能回血的将左括号多的放前面.

#include <bits/stdc++.h>
#define N 310
using namespace std;
void setIO(string s)
{
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
// freopen(out.c_str(),"w",stdout);
}
struct node
{
int x,y,z;
bool operator<(const node a) const
{
if(y>0&&a.y<=0) return 1;
if(y<0&&a.y>=0) return 0;
if(y>0) return x<a.x;
return x+y>a.x+a.y;
}
}a[N];
int f[N][N*N];
char str[N];
int main()
{
// setIO("input");
int n,m=0,i,j;
scanf("%d",&n);
for(i=1;i<=n;++i)
{
scanf("%s",str);
a[i].z=strlen(str),m+=a[i].z;
for(j=0;j<a[i].z;++j)
{
a[i].y+=(str[j]=='('?1:-1),a[i].x=max(a[i].x,-a[i].y);
}
}
sort(a+1,a+1+n);
// for(j=0;j<=m;++j) f[0][j]=-1000000000;
memset(f[0],0xc0,sizeof(f[0]));
f[0][0]=0;
for(i=1;i<=n;++i)
{
for(j=0;j<=m;++j) f[i][j]=f[i-1][j];
for(j=a[i].x;j<=m;++j)
if(j+a[i].y>=0&&j+a[i].y<=m)
f[i][j+a[i].y]=max(f[i][j+a[i].y],f[i-1][j]+a[i].z);
}
printf("%d\n",f[n][0]);
return 0;
}

  

bzoj 4922: [Lydsy1706月赛]Karp-de-Chant Number 贪心+dp的更多相关文章

  1. @bzoj - 4922@ [Lydsy1706月赛]Karp-de-Chant Number

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 卡常数被称为计算机算法竞赛之中最神奇的一类数字,主要特点集中于令 ...

  2. bzoj 4919 [Lydsy1706月赛]大根堆 set启发式合并+LIS

    4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 599  Solved: 260[Submit][Stat ...

  3. [BZOJ 4921][Lydsy1706月赛]互质序列

    传送门 因为区间 gcd 的变换不会超过 log 个,所以我们可以暴力枚举区间起点,复杂度是 n*logn 的 #include <bits/stdc++.h> using namespa ...

  4. BZOJ 4919: [Lydsy1706月赛]大根堆 set启发式合并

    这个和 bzoj 5469 几乎是同一道题,但是这里给出另一种做法. 你发现你要求的是一个树上 LIS,而序列上的 LIS 有一个特别神奇的 $O(n\log n) $ 做法. 就是维护一个单调递增的 ...

  5. BZOJ.4919.[Lydsy1706月赛]大根堆(线段树合并/启发式合并)

    题目链接 考虑树退化为链的情况,就是求一个最长(严格)上升子序列. 对于树,不同子树间是互不影响的.仿照序列上的LIS,对每个点x维护一个状态集合,即合并其子节点后的集合,然后用val[x]替换掉第一 ...

  6. [BZOJ 4923][Lydsy1706月赛]K小值查询

    传送门 势能分析平衡树,splay或treap都可以 放个指针版的就跑 #include <bits/stdc++.h> using namespace std; #define rep( ...

  7. BZOJ 4919: [Lydsy1706月赛]大根堆 启发式合并

    我不会告诉你这是线段树合并的好题的... 好吧我们可以搞一个multiset在dfs时求出LIS(自带二分+排序)进行启发式合并,轻松加愉悦... #include<cstdio> #in ...

  8. BZOJ 4919: [Lydsy1706月赛]大根堆

    F[x][i]表示x的子树中取的数字<=i的最大值,线段树合并优化DP 写得很难看,并不知道好看的写法 #include<cstdio> #include<algorithm& ...

  9. BZOJ 4919 [Lydsy1706月赛]大根堆 (SRM08 T3)

    [题解] 求一个序列的LIS有一个二分做法是这样的:f[i]表示长度为i的上升序列中最后一个数最小可以是多少,每次二分大于等于当前数字x的f[j],把f[j]修改为x:如果找不到这样的f[j],那就把 ...

随机推荐

  1. FFmpeg开发教程一、FFmpeg 版 Hello world

    本系列根据项目ffmpeg-libav-tutorial翻译而来 Chapter 0 - 万物之源 -- hello world 然而,本节的程序并不会在终端打印"Hello world&q ...

  2. SAS学习笔记49 生成前20个黄金分割数列到数据集

    黄金分割数列即斐波那契数列,该数列中后一个数与前一个数的比例越往后越接近于黄金比例(1+√5)/2 ,此数列分布表现出极致的均衡与和谐之美

  3. 面试题目<转载>

    1:检测一个变量是否有设置的函数是否?是否为空的函数是?(2分)        2:echo(),print(),print_r()的区别(3分)        3:表单中 get与post提交方法的 ...

  4. Angular Material (Components Cdk) 学习笔记 Table

    refer : https://material.angular.io/cdk/table/overview https://material.angular.io/components/table/ ...

  5. Golang官方log包详解

    Golang官方log包详解 以下全是代码, 详解在注释中, 请从头到尾看 // Copyright 2009 The Go Authors. All rights reserved. // Use ...

  6. hdu 5432

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  7. VsCode开发Angular的必备插件

    1 概述 一般个人开发或者小公司开发都会使用破解版软件,除非比较尊重正版且不太缺钱的人才会用正版,但是大型公司有严格的规定,不允许员工使用盗版软件. 这时候我就不得不从WebStorm转向VsCode ...

  8. pinfinder

    pinfinder https://pinfinder.net https://github.com/gwatts/pinfinder 关于 Pinfinder是一个小型免费程序,可以使用iPhone ...

  9. VBA switch语句

    当用户想要根据Expression的值执行一组语句时,使用Switch Case语句. 每个值被称为一个”情况”,并根据每种情况变量接通测试.如果测试表达式与用户指定的任何Case不匹配,则执行Cas ...

  10. python数据统计出海品牌

    当国内市场处于红海之中时,市场全球化已成为大势所趋.越来越多的国产品牌远走高飞,纷纷将品牌拿出来. 2019年,中国品牌十大品牌中,华为品牌力指数同比增长22%,阿里巴巴品牌力指数增长48%,小米品牌 ...