uva 1626(动态规划起步第五天 LIS变形 括号匹配)

挺简单的

先谈状态  dp[i][j]表示i---j之间的最少需要加的括号数

再谈转移  if  S 为 合法序列  那么 (S),[S] 都为合法序列,那么dp[i][j] = dp[i +1][j - 1];

if A 为合法序列  && B为合法序列  那么 AB 为合法序列  dp[i][j] = dp[i][k] + dp[k + 1][j];

所以代码

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 #define REP(i,N) for (int i = 0;i < (N);i++)
 7 #define REP_1(i,N) for (int i = 1;i < (N);i++)
 8 #define REP_2(i,be,en) for (int i = (be);i < (en);i++)
 9 #define DWN(i,N) for (int i = (N);i >= 0;i--)
10 #define DWN_1(i,N) for (int i = (N);i >= 1;i--)
11 #define DWN_2(i,en,be) for (int i = (en);i >= (be);i--)
12 #define INF 0x7fffffff
13 #define MAXN 110
14 
15 using namespace std;
16 
17 typedef long long LL;
18 char ch[MAXN];
19 int dp[MAXN][MAXN];
20 
21 bool match(char ch1,char ch2) {
22     return (ch1 == '(' && ch2 == ')') || (ch1 == '[' && ch2 == ']');
23 }
24 
25 void print(int i,int j) {
26     if (i > j) return;
27     if (i == j) {
28         if (ch[i] == '(' || ch[i] == ')') printf("()");
29         else printf ("[]");
30         return;
31     }
32     int ans = dp[i][j];
33     if (match(ch[i],ch[j]) && ans == dp[i + 1][j - 1]) {
34         cout << ch[i];print(i + 1,j - 1);cout << ch[j];
35         return;
36     }
37     REP_2(k,i,j) {
38         if (ans == dp[i][k] + dp[k + 1][j]) {
39             print(i,k);
40             print(k + 1,j);
41             return;
42         }
43     }
44 }
45 
46 int main () {
47     int T;
48     //freopen("1.txt","r",stdin);
49     cin >> T;
50     getchar();getchar();
51     while (T--) {
52         fgets(ch,MAXN,stdin);
53         int LEN = strlen(ch) - 1; // fgets读入了回车,所以 -1
54         memset(dp,0,sizeof(dp));
55         REP(i,LEN) dp[i][i] = 1;
56         REP_1(i,LEN) {
57             DWN(j,i - 1) {
58                 dp[j][i] = LEN;
59                 if (match(ch[j],ch[i])) dp[j][i] = min(dp[j][i],dp[j + 1][i - 1]);
60                 REP_2(k,j,i) {
61                      dp[j][i] = min(dp[j][i],dp[j][k] + dp[k + 1][i]);
62                 }
63             }
64         }
65         print(0,LEN - 1);
66         cout << endl;
67         if (T) cout << endl;
68         fgets(ch,MAXN,stdin);
69     }
70 }

 

posted @ 2015-02-21 14:38  闪光阳  阅读(205)  评论(0编辑  收藏  举报