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( "\n" );
        //            printf( "%d\n", d[0][len-1] );
        puts("");
        if (t) puts("");
    }
    return 0;
    
}
View Code

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

posted on 2017-08-02 16:33  FriskyPuppy  阅读(182)  评论(0编辑  收藏  举报

导航