alwaysBeAStarter

博客园 首页 新随笔 联系 订阅 管理

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=452

用dp[i][j] 记录一段序列,starts from index i, ends with index j,需要添加的char的个数。对于一段序列i~j,如果i, j 配对的话,那么dp[i][j]=dp[i+1][j-1].如果i, j不配对的话,那就需要对序列进行分割,dp[i][j]=dp[i][k]+dp[k+1][j],对k进行for loop找到最佳的k。但是当i, j配对时,并不代表dp[i+1][j-1]是最佳的结果,仍旧需要寻找最佳的k。代码如下:

  1 #include <iostream>
  2 #include <math.h>
  3 #include <stdio.h>
  4 #include <cstdio>
  5 #include <algorithm>
  6 #include <string.h>
  7 #include <string>
  8 #include <sstream>
  9 #include <cstring>
 10 #include <queue>
 11 #include <vector>
 12 #include <functional>
 13 #include <cmath>
 14 #include <set>
 15 #define SCF(a) scanf("%d", &a)
 16 #define IN(a) cin>>a
 17 #define FOR(i, a, b) for(int i=a;i<b;i++)
 18 #define Infinity 9999999
 19 typedef long long Int;
 20 using namespace std;
 21 
 22 int path[105][105];
 23 char brackets[105];
 24 void sprint(int s, int e)
 25 {
 26     if (s > e)
 27         return;
 28     if (s == e)
 29     {
 30         if (brackets[s] == '(' || brackets[s] == ')')
 31             printf("()");
 32         else
 33             printf("[]");
 34     }
 35     else
 36     {
 37         if (path[s][e] == -1)
 38         {
 39             printf("%c", brackets[s]);
 40             sprint(s + 1, e - 1);
 41             printf("%c", brackets[e]);
 42         }
 43         else
 44         {
 45             sprint(s, path[s][e]);
 46             sprint(path[s][e] + 1, e);
 47         }
 48     }
 49 }
 50 
 51 int main()
 52 {
 53     int N;
 54     SCF(N);
 55     cin.get();
 56     int len = 0;
 57     int dp[105][105];
 58     FOR(casenum, 0, N)
 59     {
 60         cin.get();
 61         cin.getline(brackets, 105);
 62         len = 0;
 63         for (len = 0; brackets[len] != '\0'; len++);
 64 
 65         if (casenum)
 66             printf("\n");
 67         if (len == 0)
 68         {
 69             printf("\n");
 70             continue;
 71         }
 72         FOR(i, 0, len)
 73         {
 74             FOR(j, 0, len)
 75                 dp[i][j] = 0;
 76         }
 77         FOR(i, 0, len)
 78             dp[i][i] = 1;
 79         int end = 0;
 80 
 81         FOR(clen, 1, len)
 82         {
 83             FOR(start, 0, len - clen)
 84             {
 85                 end = start + clen;
 86                 dp[start][end] = Infinity;
 87 
 88                 if ((brackets[start] == '(' && brackets[end] == ')') || (brackets[start] == '[' && brackets[end] == ']'))
 89                 {
 90                     dp[start][end] = dp[start + 1][end - 1];
 91                     path[start][end] = -1;
 92                 }
 93 
 94                 for (int k = start; k < end; k++)
 95                 {
 96                     if (dp[start][end] > dp[start][k] + dp[k + 1][end])
 97                     {
 98                         dp[start][end] = dp[start][k] + dp[k + 1][end];
 99                         path[start][end] = k;
100                     }
101                 }
102 
103                 
104             }
105         }
106         sprint(0, len - 1);
107         printf("\n");
108     }
109 
110     return 0;
111 }

 

posted on 2017-06-21 22:17  alwaysBeAStarter  阅读(98)  评论(0编辑  收藏  举报