zoukankan      html  css  js  c++  java
  • UVA 1626 Brackets sequence DP

      题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=825&page=show_problem&problem=4501

      题目大意: 给你一个括号序列, 要求加上最少的括号变成正确的括号序列, 输出正确括号序列

      解题思路: 我太大意了......像个傻逼, 竟然想统计括号数之差然后在前后增加括号.......我他妈是个智障.......这个题用的是DP, 先睡一觉......醒来做........(睡了一个点儿.....zzz)dp(i, j)表示区间i~j中最少需要添加的个数, 有两种状态可以转移

          dp(i, j) = dp(i+1, j-1) if( match(i, j) );

          dp(i, j) = min( dp(i+k) + dp(k+1, j) );

      两种取最小因为有可能出现()() -----> )( 的情况, 这就很尴尬了

      空串儿有效, 

      代码: 

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    using namespace std;
    
    char str[150];
    int d[150][150]; // dp(i, j)表示在str中 下标i ~ j
    
    int ok( int i, int j ) {
        if( (str[i] == '(' && str[j] == ')') || (str[i] == '[' && str[j] == ']') ) {
            return 1;
        }
        return 0;
    }
    
    
    void print( int i, int j ) {
        if( i > j ) return;
        if( i == j ) {
            if( str[i] == '(' || str[i] == ')' ) {
                printf( "()" );
                return;
            }
            else {
                printf( "[]" );
                return;
            }
        }
        if( ok( i, j ) && d[i][j] == d[i+1][j-1] ) {
            printf( "%c", str[i] );
            print( i+1, j-1 );
            printf( "%c", str[j] );
            return;
        }
        for( int k = i; k < j; k++ ) {
            if( d[i][j] == d[i][k] + d[k+1][j] ) {
                print( i, k );
                print( k+1, j );
                return;
            }
        }
    }
    int main() {
    //    freopen("in.txt", "r", stdin);
        int t;
        scanf( "%d", &t );
        getchar();
        while( t-- ) {
            memset(str, 0, sizeof(str));
            gets(str);
            gets(str);
            int len = (int)strlen(str);
            
            for( int i = 0; i < len; i++ ) {
                d[i+1][i] = 0;
                d[i][i] = 1;
            }
            for( int i = len-2; i >= 0; i-- ) {
                for( int j = i+1; j < len; j++ ) {
                    int & ans = d[i][j];
                    ans = len;
                    if( ok( i, j ) ) ans = min( ans, d[i+1][j-1] );
                    for( int k = i; k < j; k++ ) {
                        d[i][j] = min( d[i][j], d[i][k] + d[k+1][j]);
                    }
                }
            }
            print(0, len-1);
    //        printf( "
    " );
            //            printf( "%d
    ", d[0][len-1] );
            puts("");
            if (t) puts("");
        }
        return 0;
        
    }
    View Code

      思考: 好好读题, 认真思考, 我发现递归这个东西就是做的题多了.....自己脑子中就自动有一种递归的想法了, 有了这种想法就能跟着感觉走了.....继续肝吧

  • 相关阅读:
    tab切换与表格展示
    ajax
    api
    slice() 方法
    iframe跳转
    快排序
    【问题排查】cpu占用过高排查
    LOJ6013 负载平衡 [最小费用最大流]
    随机序列 [思维题, 组合数]
    P1777 帮助 [状压dp]
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7274690.html
Copyright © 2011-2022 走看看