题目链接: 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; }
思考: 好好读题, 认真思考, 我发现递归这个东西就是做的题多了.....自己脑子中就自动有一种递归的想法了, 有了这种想法就能跟着感觉走了.....继续肝吧