• bzoj 4922: [Lydsy1706月赛]Karp-de-Chant Number 贪心+dp


    题意:给定 $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
    ",f[n][0]); 
        return 0; 
    }
    

      

  • 相关阅读:
    [haoi2009]逆序对数列
    [haoi2008]木棍分割
    【LibreOJ 6277】数列分块入门 1 (分块)
    【模板】 最大流模板(ISAP)
    【模板】最大流模板(dinic)
    [模板] zkw线段树
    [luogu P1962] 斐波那契数列(带快速幂矩阵乘法模板)
    [SCOI2010] 股票交易 (单调队列优化dp)
    [luogu P2285] [HNOI2004]打鼹鼠
    [poj 2152] fire (树形dp)
  • 原文地址:https://www.cnblogs.com/guangheli/p/11765125.html
Copyright © 2020-2023  润新知