• POJ 1141:Brackets Sequence


    题意:

    定义合法串为(),[]以及他们的并列组合如()[],()(),或嵌套组合如([]),(())。 其实正常理解就好~

    然后给你一个串,让你求出把它改对后的最短合法串。

    类型:

    DP动态规划

    思路:

    当我拿到一个字符i, 那么在一种最优结果中,它只有这么两种结果:要么和某个字符匹配,要么不匹配。

    定义状态:

    dp[i][j]为  i到j的子串中  所能做到的最大匹配数符号数。

    最大匹配符号数说明:如(([))]] 如果这么匹配(([))]]   数量为2,  而这样匹配 (([))]] 数量为4。易知后者也是最大的,所以这个子串最大匹配符号数为4.

    状态转移:

    首先特判:若i所在字符与j所在字符能匹配(() 或 []) 那么尝试匹配这两个字符

    ans = dp[i+1][j-1] + 2;

    然后,不匹配ij两个字符,尝试把字符串分成两段(i,i+k) (i+k+1, j)(那么这里其实是假想让i字符与当中第i+k个字符匹配,当k=0时其实就是不匹配。k从0到j-i-1)

    代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    //18:09
    
    char str[200];
    int dp[120][120];
    int flag[200][200];
    int chooes[200];
    
    int dfs(int i, int j)
    {
        if (dp[i][j] != -1) return dp[i][j];
        if (j - i < 1) return dp[i][j] = 0;
    
        int &ans = dp[i][j];
        if (str[i] == '(' && str[j] == ')' || str[i] == '[' && str[j] == ']')
        {
            ans = dfs(i+1, j-1) + 2;
            flag[i][j] =  -99;
        }
        int k;
        for (k = 0; k < j-i; k++)
        {
            if (ans < dfs(i,i+k) + dfs(i+k+1, j)) {
                ans = dfs(i,i+k) + dfs(i+k+1, j);
                flag[i][j] = k;
            }
        }
    
        return ans;
    }
    
    int main()
    {
        //while (scanf("%s", str+1) != EOF)
        scanf("%s", str+1);
        {
            memset(dp, -1, sizeof(dp));
            memset(chooes, 0, sizeof(chooes));
    
            int len = strlen(str+1);
    
            dfs(1, len);
    
            // Use stack to find which is choosen
            int i = 1; int j = len;
            int si[200], sj[200];
            int pi = 0, pj = 0;
            si[pi++] = 1;
            sj[pj++] = len;
    
            while (pj) {
                i = si[--pi];
                j = sj[--pj];
                if (flag[i][j] == -99) {  //Choosen
                    chooes[i] = chooes[j] = 1;
                    si[pi++] = i+1;
                    sj[pj++] = j-1;
                } else if (j-i>=1) {
                    si[pi++] = i;
                    sj[pj++] = i+flag[i][j];
    
                    si[pi++] = i+flag[i][j]+1;
                    sj[pj++] = j;
                }
            }
    
    
            for (i = 1; i <= len; i++) {
                if (chooes[i]) putchar(str[i]); // Those who is choosen needn't to fix
                else {
                    switch (str[i]) {
                        case '(':
                        case ')':  printf("()");break;
                        case '[':
                        case ']':  printf("[]");break;
                    }
                }
            }
            puts("");
        }
        return 0;
    }
    POJ 1141:Brackets Sequence O(n2)
  • 相关阅读:
    mysql表结构同步
    关于Java8中lambda约简函数reduce的一个计算问题
    激烈的歌曲有助于编程
    今天刷了数据解构与算法这门课 感觉略有收获
    我有一个好朋友 他的名字叫刘洋 他的ID是北极的大企鹅 他的技术不错 他渴望成为架构师 猎头们路过可以去他的博客看看
    缓存雪崩,缓存击穿,缓存穿透
    celery
    Redis
    django 缓存的使用
    base64 加密
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3080198.html
Copyright © 2020-2023  润新知