UVa 1626 括号序列——区间DP

来源:互联网 发布:java小数点保留两位 编辑:程序博客网 时间:2024/06/08 11:25

这题坑在输入输出,注意输入时两两之间有空行,输出时两两之间也有空行,而且紫书上的输出函数执行后时不带换行的

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <string>using namespace std;char str[110];int dp[110][110];//表示闭区间[i,j]需要添加的最小括号数int n;//str长度bool match(char a, char b){    if (a == '(' && b == ')') return true;    if (a == '[' && b == ']') return true;    return false;}void DP() {    for (int i = 0; i < n; i++) {        dp[i + 1][i] = 0;        dp[i][i] = 1;    }    for (int i = n - 2; i >= 0; i--) {        for (int j = i + 1; j < n; j++) {            dp[i][j] = j - i + 1;            if (match(str[i], str[j])) {                dp[i][j] = min(dp[i][j], dp[i + 1][j - 1]);            }            for (int k = i; k < j; k++) {                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);            }        }    }}void output(int i, int j) {    if (i > j) return;    if (i == j) {        if (str[i] == '(' || str[i] == ')') {            printf("()");        }        else printf("[]");        return;    }    int ans = dp[i][j];    if (match(str[i], str[j]) && ans == dp[i + 1][j - 1]) {        printf("%c", str[i]);        output(i + 1, j - 1);        printf("%c", str[j]);        return;    }    for (int k = i; k < j; k++) {        if (ans == dp[i][k] + dp[k + 1][j]) {            output(i, k);            output(k + 1, j);            return;        }    }}int main(){    int T; scanf("%d", &T); getchar();    int flag = 0;    while (T--) {        getchar();        gets(str);        n = strlen(str);        DP();        if (flag++) printf("\n");        output(0, n - 1);        printf("\n");    }    return 0;}


原创粉丝点击