poj1141

题意:定义如下规则序列(字符串): 
         空序列是规则序列;
         如果S是规则序列,那么(S)和[S]也是规则序列;
         如果A和B都是规则序列,那么AB也是规则序列。
         例如,下面的字符串都是规则序列:
        (), [], (()), ([]), ()[], ()[()]
        这几个则不是规则序列:
        (, [, ], )(, ([()
        现在,给出一些由‘(’,‘)’,‘[’,‘]’构成的序列,请添加尽量少的括号,得到一个规则序列。
思路:
     黑书上的题目。经典dp
     f[i][j]表示i..j这一段匹配完所需要添加的最少字母数
     方程:f[i][j] = min(f[i][k] + f[k+1][j])                                    ( S[I] != S[J]) 
              f[i][j] =  min(f[i][k] + f[k+1][j] , f[i+1][j-1]);                (S[I] == S[J])
             其中, i <k <j
     边界: f[i][i] = 1;
 1 /*
 2  State:Accepted
 3  Time:2013.3.1
 4  */
 5 
 6 #include <iostream>
 7 #include <cstdlib>
 8 #include <string>
 9 #include <cstdio>
10 #include <algorithm>
11 #include <cmath>
12 #include <algorithm>
13 #include <vector>
14 #include <set>
15 #include <cstring>
16 #define Inf  100000;
17 using namespace std;
18 char s[200] ,s1[200];
19 int n , f[200][200] ,map[200][200];
20 
21 void init(){
22      scanf("%s",&s1);  
23      for (int i = 0; i < strlen(s1) ; ++i)   
24        s[i + 1] = s1[i];;
25      n = strlen(s1);   
26 }
27 
28 bool check(char word1, char word2){
29      if (word1 == '(' && word2 == ')') return true;
30      if (word1 == '[' && word2 == ']') return true;
31      return false;
32 }
33 
34 void dp(){
35      int j ,temp;
36      for (int i = 1; i <= n; ++i)
37          for (int j = i; j <= n; ++j)
38             f[i][j] =  Inf;
39      for (int i = 1; i <= n ; ++i )
40           f[i][i] = 1;
41         
42      for (int l = 2; l <= n; ++ l)
43        for (int i = 1; i <= n - l + 1; ++i){
44             j = i + l -1;
45             if (check(s[i],s[j]))  f[i][j] = min(f[i][j] , f[i + 1][j - 1] );
46             for (int k = 1; k < l; ++k){
47                   temp = f[i][i + k -1] + f[i + k][j];
48                   if (temp < f[i][j]) {
49                            f[i][j] = temp;
50                            map[i][j] = i + k -1;
51                   }
52             }
53             
54        }
55 }
56 
57 void print(int  l , int r){
58      if (l > r) return;
59      if (l == r){
60             if (s[l] == '[' || s[l] == ']')
61             printf("[]"); 
62             else    printf("()");
63             return;
64      }
65      if (map[l][r] == 0){
66             printf("%c",s[l]); 
67             print(l + 1 ,r - 1);
68             printf("%c",s[r]);
69      }  else {
70                  print(l ,map[l][r]);
71                  print(map[l][r] + 1 , r);
72              
73              }
74      
75 }
76 
77 int main(){
78      freopen("poj1141.in","r",stdin);
79      freopen("poj1141.out","w",stdout);
80      init();
81      dp();
82      print(1 , n);
83      printf("\n");
84      fclose(stdin); fclose(stdout);
85 }

 

 

  

posted on 2013-03-23 19:53  yzcstc  阅读(211)  评论(0编辑  收藏  举报