题目出处:http://acm.pku.edu.cn/JudgeOnline/problem?id=1141
版权声明:版权归作者WeiSteven所有,转载请注明!
基本题意是给定一个只包含()[]的字符串,题目要求算法能够求的包含这个字符串的最短的匹配字符串。
(匹配字符串指满足成对,且成对里面的字符串也是成对的)
比如:
([
包含它的最短字符串是()[]或者([])
两个都是满足题意的,所以此题不一定只有一个解(Special Judge)
题目可以用DP来做:
DP[i][j]:指字符串i~~~j中字符串能够匹配的最短字符串
状态转移方程:DP[i][j]=min(DP[i][m]+DP[m][j]),其中m是从i+1到j-1的。
打印出的字符串也是通过递归来完成的。
1
#include
<
iostream
>
2 #include < string .h >
3 using namespace std;
4 string s;
5 int d[ 101 ][ 101 ],p[ 101 ][ 101 ],len;
6 void dp(){
7 for ( int i = 0 ;i < len;i ++ ) d[i][i] = 1 ;
8 for ( int k = 1 ;k < len;k ++ )
9 for ( int i = 0 ;i < len - k;i ++ )
10 { int j = i + k;
11 if ((s[i] == ' ( ' && s[j] == ' ) ' ) || (s[i] == ' [ ' && s[j] == ' ] ' )){d[i][j] = d[i + 1 ][j - 1 ];p[i][j] =- 1 ;}
12 else
13 d[i][j] = 65535 ;
14 for ( int m = i;m < j;m ++ )
15 if (d[i][j] > d[i][m] + d[m + 1 ][j]){
16 d[i][j] = d[i][m] + d[m + 1 ][j];
17 p[i][j] = m;
18 }
19
20 }
21 }
22 void output( int i, int j){
23 if (i > j) return ;
24 if (i == j){
25 switch (s[i]){
26 case ' ) ' : case ' ( ' :cout << " () " ; break ;
27 case ' ] ' : case ' [ ' :cout << " [] " ; break ;
28 }
29 } else if (p[i][j] == - 1 ){
30 cout << s[i];output(i + 1 , j - 1 );cout << s[j];
31 } else {output(i,p[i][j]);output(p[i][j] + 1 ,j);}
32 }
33 int main(){
34 while (getline(cin,s)){
35 memset(d, 0 , sizeof (d));
36 len = s.length();
37 dp();
38 output( 0 ,len - 1 );
39 cout << endl;
40 }
41 return 0 ;
42 }
2 #include < string .h >
3 using namespace std;
4 string s;
5 int d[ 101 ][ 101 ],p[ 101 ][ 101 ],len;
6 void dp(){
7 for ( int i = 0 ;i < len;i ++ ) d[i][i] = 1 ;
8 for ( int k = 1 ;k < len;k ++ )
9 for ( int i = 0 ;i < len - k;i ++ )
10 { int j = i + k;
11 if ((s[i] == ' ( ' && s[j] == ' ) ' ) || (s[i] == ' [ ' && s[j] == ' ] ' )){d[i][j] = d[i + 1 ][j - 1 ];p[i][j] =- 1 ;}
12 else
13 d[i][j] = 65535 ;
14 for ( int m = i;m < j;m ++ )
15 if (d[i][j] > d[i][m] + d[m + 1 ][j]){
16 d[i][j] = d[i][m] + d[m + 1 ][j];
17 p[i][j] = m;
18 }
19
20 }
21 }
22 void output( int i, int j){
23 if (i > j) return ;
24 if (i == j){
25 switch (s[i]){
26 case ' ) ' : case ' ( ' :cout << " () " ; break ;
27 case ' ] ' : case ' [ ' :cout << " [] " ; break ;
28 }
29 } else if (p[i][j] == - 1 ){
30 cout << s[i];output(i + 1 , j - 1 );cout << s[j];
31 } else {output(i,p[i][j]);output(p[i][j] + 1 ,j);}
32 }
33 int main(){
34 while (getline(cin,s)){
35 memset(d, 0 , sizeof (d));
36 len = s.length();
37 dp();
38 output( 0 ,len - 1 );
39 cout << endl;
40 }
41 return 0 ;
42 }