zoukankan      html  css  js  c++  java
  • bzoj4922-Karp-de-Chant Number

    题意

    给出 (n) 个括号序列 (s_i),求把它们拼成一个合法括号序列,最长的长度是多少。(n,|s_i|in [1,300])

    分析

    把左括号看成 1,右括号看成 -1,很容易想到dp f[i][j] 表示前 (i) 个括号序列,组成一个和为 (j) 的括号序列,且任意一个位置的前缀和都大于等于 0 的最长长度。这其实是一个背包模型。

    关键是dp的顺序。一个括号序列进行消括号最后会变成 ))))(((( 这种样子,设它的和为 (s) ,右括号个数为 (m)

    贪心地决定dp顺序。显然先填 (sge 0) ,后填 (s<0) 。在 (sge 0) 中,为了更优,一定是按 (m) 从小到大填,这样可以保证总和不断增加或不变,并且尽量合法。

    对于 (s<0) 的处理,不妨把答案序列看成两部分,由左边的 (sge 0) 和右边的 (s<0) 拼起来,那么从右边往左边看,贪心地来说,左括号的个数是从小到大的,所以正常来看,左括号从大到小。

    由于 (s) 可正可负,所以在dp的过程中要考虑从前往后还是从后往前做。

    这题关键是用贪心决定dp顺序。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=301;
    const int maxm=maxn*maxn;
    char s[maxn][maxn];
    struct A {
    	int sum,mi,len;
    	inline bool operator < (const A &b) const {
    		if (sum>=0 && b.sum<0) return true; else
    		if (b.sum>=0 && sum<0) return false;
    		if (sum>=0 && b.sum>=0) return mi>b.mi;
    		if (sum<=0 && b.sum<=0) return sum-mi>b.sum-b.mi;
    	}
    } a[maxn];
    int n,f[maxm],mx=0;
    inline void Min(int &x,int y) {x=min(x,y);}
    inline void Max(int &x,int y) {x=max(x,y);}
    inline void deal(int id,char s[]) {
    	int &l=a[id].len=strlen(s+1);
    	int &t=a[id].mi=0,&sm=a[id].sum=0;
    	for (int i=1;i<=l;++i) Min(t,sm+=(s[i]=='('?1:-1));
    }
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	scanf("%d",&n);
    	for (int i=1;i<=n;++i) {
    		scanf("%s",s[i]+1);
    		deal(i,s[i]);
    	}
    	sort(a+1,a+n+1);
    	memset(f,0xbf,sizeof f);
    	f[0]=0;
    	for (int i=1;i<=n;++i) {
    		mx+=a[i].len;
    		if (a[i].sum<0) for (int j=a[i].sum-a[i].mi;j<=mx;++j) Max(f[j],f[j-a[i].sum]+a[i].len); else 
    		for (int j=mx;j>=a[i].sum-a[i].mi;--j) Max(f[j],f[j-a[i].sum]+a[i].len);
    	}
    	printf("%d
    ",max(0,f[0]));
    	return 0;
    }
    
  • 相关阅读:
    关于hexo-abbrlink链接undefined
    如何修改layer-layui中的confirm
    cmder的segmentation fault错误修复
    论好的代码习惯的养成/做一个优雅的coder
    50行代码写的一个插件,破解一个H5小游戏
    慎用array_filter函数
    python:if 语句的使用方法
    python:for语句的使用方法
    关于python3 发送邮件
    zookpeer的安装与配置
  • 原文地址:https://www.cnblogs.com/owenyu/p/7542352.html
Copyright © 2011-2022 走看看