9-10

状态转移说明了原问题的子结构。下面的代码修改了打印方法。

#define _CRT_SECURE_NO_WARNINGS 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <numeric>

using namespace std;

const int maxn = 100 + 5;
char str[maxn];
int n, d[maxn][maxn];

int s[maxn][maxn];

bool match(char a, char b) {
    return (a == '(' && b == ')') || (a == '[' && b == ']');
}

void dp() {
    for (int i = 0; i < n; i++) {
        d[i + 1][i] = 0;
        d[i][i] = 1;
    }
    for (int i = n - 2; i >= 0; i--)
        for (int j = i + 1; j < n; j++) {
            d[i][j] = n; // maxium value of d[i][j] is n
            if (match(str[i], str[j])) 
                d[i][j] = min(d[i][j], d[i + 1][j - 1]); // if j == i + 1, d[i + 1][j - 1] == d[i + 1][i] == 0
            for (int k = i; k < j; k++)
                d[i][j] = min(d[i][j], d[i][k] + d[k + 1][j]);
        }
}

void print(int i, int j) {
    if (i > j) return;

    if (i == j) {
        if (str[i] == '(' || str[i] == ')') // if '(' append ')' after it, if ')' append '(' before it
            printf("()");
        else // str[i] == '[' || str[i] == ']'
            printf("[]");
        return;
    }

    int ans = d[i][j];

    if (match(str[i], str[j]) && ans == d[i + 1][j - 1]) {
        printf("%c", str[i]); 
        print(i + 1, j - 1); 
        printf("%c", str[j]);
        return;
    }

    for (int k = i; k < j; k++)
        if (ans == d[i][k] + d[k + 1][j]) {
            print(i, k); 
            print(k + 1, j);
            return;
        }
}


void dp2()
{
    for (int i = 0; i < n; i++){
        d[i][i] = 1;
        d[i + 1][i] = 0;
    }

    for (int i = n - 2; i >= 0; i--){
        for (int j = i + 1; j <= n - 1; j++){
            d[i][j] = n;
            if (match(str[i], str[j])){
                if (d[i + 1][j - 1] < d[i][j]){
                    d[i][j] = d[i + 1][j - 1];
                    s[i][j] = -1;
                }
            }

            for (int k = i; k < j; k++){
                if (d[i][k] + d[k + 1][j] < d[i][j]) {
                    d[i][j] = d[i][k] + d[k + 1][j];
                    s[i][j] = k;
                }
            }
        }
    }
}

void print2(int i, int j)
{
    if (i > j) return;

    if (i == j) {
        if (str[i] == '(' || str[i] == ')')
            printf("()");
        else
            printf("[]");

        return;
    }

    if (s[i][j] == -1) {
        printf("%c", str[i]);
        print2(i + 1, j - 1);
        printf("%c", str[j]);
    }
    else {
        print2(i, s[i][j]);
        print2(s[i][j] + 1, j);
    }
}

void readline(char* str) {
    fgets(str, maxn, stdin);
}

int main()
{
    int T;
    readline(str); // read a line into str
    sscanf(str, "%d", &T); // parse the line

    readline(str); // a blank line

    while (T--){
        readline(str);
        n = strlen(str) - 1;
        memset(d, -1, sizeof(d));
        memset(s, 0, sizeof(s));
        /*
        dp();
        print(0, n - 1);
        */
        dp2();
        print2(0, n-1);

        printf("\n");
        if (T) printf("\n");
        readline(str); // a blank line
    }

    return 0;
}

 

posted @ 2016-09-06 09:57  PatrickZhou  阅读(148)  评论(0编辑  收藏  举报