zoukankan      html  css  js  c++  java
  • POJ 2955 括号匹配,区间DP

    题意:给你一些括号,问匹配规则成立的括号的个数。

    思路:这题lrj的黑书上有,不过他求的是添加最少的括号数,是的这些括号的匹配全部成立。

    我想了下,其实这两个问题是一样的,我们可以先求出括号要匹配的最少数量,那么设原来括号的数量为l , 添加了l' 。

    那么其实原来括号匹配成功的括号数就是((l + l') / 2 - l') * 2。

    #define N 105
    char a[N] ;
    int dp[N][N] ;
    int f[N][N] ;
    int check(int i ,int j) {
        if(a[i] == '[' && a[j] == ']')return 1 ;
        if(a[i] == '(' && a[j] == ')')return 1 ;
        return 0 ;
    }
    void init() {
        mem(dp ,0) ;
        mem(f ,0) ;
    }
    int main() {
        while(cin >> a) {
            if(strcmp(a , "end") == 0)break ;
            init() ;
            int l = strlen(a) ;
            for (int i = 0 ; i < l ; i ++ ) {
                dp[i][i] = 1 ;
                dp[i + 1][i] = 0 ;
            }
            for (int i = 1 ; i <= l ; i ++ ) {
                for (int j = 0 ; j + i - 1 < l ; j ++ ) {
                    int s = j ;
                    int e = j + i - 1 ;
                    dp[s][e] = 0 ;
                    if(check(s ,e))dp[s][e] = min(dp[s][e] , dp[s + 1][e - 1]) ;
                    if(a[s] == '[' || a[s] == '(')dp[s][e] = min(dp[s][e] , dp[s + 1][e] + 1) ;
                    if(a[e] == ']' || a[e] == ')')dp[s][e] = min(dp[s][e] , dp[s][e - 1] + 1) ;
                    for (int k = s ; k < e ; k ++ ){
                        dp[s][e] = min(dp[s][e] , dp[s][k] + dp[k + 1][e]) ;
                    }
                }
            }
            cout << ((l + dp[0][l - 1]) / 2 - dp[0][l - 1]) * 2 << endl;
        }
        return 0 ;
    }
    

    当然,按照思路来写应该是这样的区间dp。

    #define N 105
    int dp[N][N] ;
    char a[N] ;
    bool check(int i ,int j){
        if(a[i] == '[' && a[j] == ']')return 1 ;
        if(a[i] == '(' && a[j] == ')')return 1 ;
        return 0 ;
    }
    int main() {
        int T ;
        while(cin >> a){
            if(strcmp(a ,"end") == 0)break ;
            int l = strlen(a) ;
            mem(dp , 0) ;
            for (int i = 2 ; i <= l ; i ++ ){
                for (int j = 0 ; j + i - 1 < l ; j ++ ){
                    int s = j ;
                    int e = j + i - 1 ;
                    if(check(s ,e ))dp[s][e] = max(dp[s][e] , dp[s + 1][e - 1] + 2) ;
                    for (int k = s ; k < e ; k ++ ){
                        dp[s][e] = max(dp[s][e] , dp[s][k] + dp[k + 1][e]) ;
                    }
                }
            }
            cout << dp[0][l - 1] << endl;
        }
        return 0 ;
    }
    


  • 相关阅读:
    java常用配置文件头部声明
    Error while launching application Error: spawn ENOMEM 解决
    Maven添加依赖后如何在IDEA中引用
    2017-2018 ACM-ICPC East Central North America Regional Contest (ECNA 2017)部分题解
    最小一乘法的一种数值算法?
    LOJ 6409. 「ICPC World Finals 2018」熊猫保护区
    min-max容斥复习
    BMCH
    大象
    关于高维卷积的一些不成熟的想法
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3235427.html
Copyright © 2011-2022 走看看