//o(∩_∩)o...哈哈,我回来做题了……
POJ1141是一个经典DP题,是一个“历史遗留”问题了。
一个简单版本
WOJ1077:Dragonflywww
http://acm.whu.edu.cn/oak/problem/problem.jsp?problem_id=1077题目描述:
给出一个由(、)、[、]组成的字符串,添加最少的括号使得所有的括号匹配,输出最后得到的字符串。
解题思路:
用DP求最少需要括号数:以p从1到n(字符串长度),记录下从i到i+p需要添加的最少括号数f[i][j],同时记录下中间需要添加括号的位置pos[i][j]——为-1表示不需要添加。这种方法我原来就知道,所以过了WOJ1077。
最麻烦的就是添加括号构造字符串了,这里借鉴别人的方法用递归实现,程序里写得很清楚了,要利用pos[i][j]。
1 /*************************************************************************
2 Author: littlekid
3 Created Time: 1/9/2008 7:04:26 PM
4 Problem Source: POJ1141
5 Description:
6 ************************************************************************/
7 # include <stdio.h>
8 # include <string.h>
9 # include <stdlib.h>
10
11 # define N 222
12
13 const int maxint=0x7FFFFFFF;
14 typedef long long int64;
15 const int64 maxint64 = 0x7FFFFFFFFFFFFFFFLL;
16
17 int f[ N ][ N ], pos[ N ][ N ];
18 char s[ N ];
19 int n;
20
21 inline int MIN( int a, int b )
22 {
23 return a > b ? b : a;
24 }
25
26 void init()
27 {
28 scanf( "%s", &s );
29 }
30
31 void output()
32 {
33 printf( "%d\n", f[ 1 ][ n ] );
34 for ( int i = 1; i <= n; i ++ )
35 {
36 for ( int j = 1; j <= n; j ++ )
37 {
38 printf( "%c ", f[ i ][ j ] );
39 }
40 printf( "\n" );
41 }
42 }
43
44 void recur(int beg, int end)
45 {
46 if( beg > end ) return ;
47
48 if( beg == end )
49 {
50 if( s[ beg ] == '(' || s[ beg ] == ')' )
51 {
52 printf( "()" );
53 }
54 else printf( "[]" );
55 }
56 else
57 {
58 if( pos[ beg ][ end ] == -1 )
59 {
60 if( s[ beg ] == '(' )
61 {
62 printf( "(" );
63 recur( beg+1, end-1 );
64 printf( ")" );
65 }
66 else
67 {
68 printf( "[" );
69 recur( beg+1, end-1 );
70 printf( "]" );
71 }
72 }
73 else
74 {
75 recur( beg, pos[ beg ][ end ] );
76 recur( pos[ beg ][ end ]+1, end );
77 }
78 }
79 }
80
81 int DP()
82 {
83 n = strlen( s );
84 memset( f, 0, sizeof( f ));
85
86 for ( int i = n; i > 0; i -- )
87 {
88 s[ i ] = s[ i-1 ];
89 f[ i ][ i ] = 1;
90 }
91
92 int tmp;
93 for ( int p = 1; p <= n; p ++ )
94 {
95 for ( int i = 1; i <= n-p; i ++ )
96 {
97 int j = i + p;
98 f[ i ][ j ] = maxint;
99 if ( ( s[ i ] == '(' && s[ j ] == ')' ) || ( s[ i ] == '[' && s[ j ] == ']' ) )
100 {
101 tmp = f[ i+1 ][ j-1 ];
102 if ( tmp < f[ i ][ j ] )
103 {
104 f[ i ][ j ] = tmp;
105 }
106 }
107 pos[ i ][ j ] = -1;
108 for ( int k = i; k < j; k ++ )
109 {
110 tmp = f[ i ][ k ] + f[ k+1 ][ j ];
111 if ( tmp < f[ i ][ j ] )
112 {
113 f[ i ][ j ] = tmp;
114 pos[ i ][ j ] = k;
115 }
116 }
117 }
118 }
119 return f[ 1 ][ n ];
120 }
121
122 int main()
123 {
124 //while ( scanf("%s", &s ) != EOF ){
125 init();
126 DP();
127 //output();
128 recur( 1, n );
129 printf( "\n" );
130 //}
131 return 0;
132 }
133
134
posted on 2008-01-09 21:40
R2 阅读(1303)
评论(0) 编辑 收藏 引用 所属分类:
Problem Solving