• UVA


    题意:给定一个串,可能空串,或由'[',']','(',')'组成。问使其平衡所需添加最少的字符数,并打印平衡后的串。

    分析:dp[i][j]表示区间(i,j)最少需添加的字符数。

    1、递推。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define lowbit(x) (x & (-x))
    const double eps = 1e-8;
    inline int dcmp(double a, double b){
        if(fabs(a - b) < eps) return 0;
        return a > b ? 1 : -1;
    }
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
    const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const int MAXN = 100 + 10;
    const int MAXT = 10000 + 10;
    using namespace std;
    char s[MAXN];
    int dp[MAXN][MAXN];
    int len;
    bool match(char a, char b){//判断是否平衡
        return (a == '(' && b == ')') || (a == '[' && b == ']');
    }
    void solve(){
        for(int i = 0; i < len; ++i){
            dp[i + 1][i] = 0;//l>r,该情况不需添加字符
            dp[i][i] = 1;//只有一个字符,无论是什么,都需要一个字符将其补全
        }
        for(int i = len - 2; i >= 0; --i){
            for(int j = i + 1; j < len; ++j){
                dp[i][j] = len;//len长度的串,最多就需要len个字符使其平衡,此处初始化成个最大值即可
                if(match(s[i], s[j])){//如果当前串满足(S)或[S],则转移到S这个情况。
                    dp[i][j] = min(dp[i][j], dp[i + 1][j - 1]);
                }
                for(int k = i; k < j; ++k){//在当前区间里枚举分割线
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
                }
            }
        }
    }
    void print(int i, int j){
        if(i > j) return;
        if(i == j){
            if(s[i] == '(' || s[i] == ')') printf("()");
            else printf("[]");
            return;
        }
        int ans = dp[i][j];
        if(match(s[i], s[j]) && ans == dp[i + 1][j - 1]){
            printf("%c", s[i]);
            print(i + 1, j - 1);
            printf("%c", s[j]);
            return;
        }
        for(int k = i; k < j; ++k){
            if(ans == dp[i][k] + dp[k + 1][j]){
                print(i, k);
                print(k + 1, j);
                return;
            }
        }
    }
    int main(){
        int T;
        scanf("%d", &T);
        getchar();
        while(T--){
            gets(s);
            gets(s);
            len = strlen(s);
            solve();
            print(0, len - 1);
            printf("
    ");
            if(T) printf("
    ");
        }
        return 0;
    }

    2、记忆化搜索,更好理解些。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define lowbit(x) (x & (-x))
    const double eps = 1e-8;
    inline int dcmp(double a, double b){
        if(fabs(a - b) < eps) return 0;
        return a > b ? 1 : -1;
    }
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
    const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const int MAXN = 100 + 10;
    const int MAXT = 10000 + 10;
    using namespace std;
    char s[MAXN];
    int dp[MAXN][MAXN];
    int len;
    bool match(char a, char b){
        return (a == '(' && b == ')') || (a == '[' && b == ']');
    }
    int solve(int i, int j){
        if(dp[i][j] != INT_INF) return dp[i][j];
        if(i > j) return dp[i][j] = 0;
        if(i == j) return dp[i][j] = 1;
        if(match(s[i], s[j])) dp[i][j] = min(dp[i][j], solve(i + 1, j - 1));
        for(int k = i; k < j; ++k){//枚举分割线,串AB所需添加的最少字符数可转移到串A所需添加的最少字符数+串B所需添加的最少字符数
            dp[i][j] = min(dp[i][j], solve(i, k) + solve(k + 1, j));
        }
        return dp[i][j];
    }
    void print(int i, int j){
        if(i > j) return;
        if(i == j){
            if(s[i] == '(' || s[i] == ')') printf("()");
            else printf("[]");
            return;
        }
        int ans = dp[i][j];
        if(match(s[i], s[j]) && ans == dp[i + 1][j - 1]){
            printf("%c", s[i]);
            print(i + 1, j - 1);
            printf("%c", s[j]);
            return;
        }
        for(int k = i; k < j; ++k){
            if(ans == dp[i][k] + dp[k + 1][j]){
                print(i, k);
                print(k + 1, j);
                return;
            }
        }
    }
    int main(){
        int T;
        scanf("%d", &T);
        getchar();
        while(T--){
            memset(dp, INT_INF, sizeof dp);
            gets(s);
            gets(s);
            len = strlen(s);
            solve(0, len - 1);
            print(0, len - 1);
            printf("
    ");
            if(T) printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    lr 增强窗格中,如何生成调试信息?
    lr 自带的例子,如何进行关联,通过代码的函数进行实现
    lr11 录制脚本时候,无法自动启动ie,查了网上很多方法都未解决?
    loadrunner11 录制脚步不成功,在录制概要出现“No Events were detected”,浮动窗口总是显示“0 Events”,解决办法
    loadrunner11 安装及破解教程来自百度文库
    安装loadrunner11 ,出现如下错误如何解决?
    回收站数据删除了,如何进行恢复?
    网管工作方面——————打印机删除了然后开机重启他依然存在,如何解决
    Windows 不能在 本地计算机 启动 SQL Server 服务 错误代码126
    Sorry, the page you are looking for is currently unavailable. Please try again later. Nginx
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/7359676.html
Copyright © 2020-2023  润新知