zoukankan      html  css  js  c++  java
  • 【bzoj4922】[Lydsy六月月赛]Karp-de-Chant Number 贪心+背包dp

    题目描述

    给出 $n$ 个括号序列,从中选出任意个并将它们按照任意顺序连接起来,求以这种方式得到匹配括号序列的最大长度。

    输入

    第一行包含一个正整数n(1<=n<=300),表示括号序列的个数。
    接下来n行,每行一个长度在[1,300]之间的括号序列,仅由小括号构成。

    输出

    输出一行一个整数,即最大长度,注意你可以一个序列也不选,此时长度为0。

    样例输入

    3
    ())
    ((()
    )()

    样例输出

    10


    题解

    贪心+背包dp

    首先对于一个括号序列,有用的只有:长度、消耗'('的数目、以及'('减去')'的数目。

    显然可以dp,但是由于顺序对于本题来说时有用的,因此不能直接dp。

    进一步思考可以发现:本题和【bzoj4619】[Wf2016]Swap Space 相同,因此可以按照那道题的贪心策略来决定选择的顺序。

    即:先选择'('多于')'的,对于'('多于')'的按照消耗'('的数目从小到大排序,否则按照多出来'('(即'('减去')'的数目+消耗'('的数目)从大到小排序。

    确定了顺序后就好办了。设 $f[i][j]$ 表示排序后前 $i$ 个括号序列,多出来'(' 的数目为 $j$ 的最大长度。那么这是一个背包问题。当 $j$ 大于等于消耗 '(' 的数目时能够转移。

    最后的答案就是 $f[n][0]$ 。

    时间复杂度 $O(n^3)$

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 310
    using namespace std;
    struct data
    {
        int x , y , z;
        bool operator<(const data &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()
    {
        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 + n + 1);
        memset(f , 0xc0 , sizeof(f)) , 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;
    }
    

     

  • 相关阅读:
    CentOS7安装Dnsmasq并更新最新版
    VMware vCenter Server Appliance(VCSA )6.7 部署,许可证破解
    vsphere6.7虚拟机与ESXI时间同步
    oracle使用存储过程返回数据集
    如何让CheckBoxList横着显示
    在oracle中创建自动增长字段
    oracle 11g安装客户端后使用ps/sql连接提示TNS适配器错误的解决办法
    myeclipse 网站项目部署失败
    Opera Dragonfly本地化
    ExtJs的fireEvent事件
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8016927.html
Copyright © 2011-2022 走看看