题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=4501&mosmsg=Submission+received+with+ID+26616028
区间dp
如果 s 形如 '(s)' 或 '[s]',则可转移到 s
如果 s 至少有两个字符,则可分解成两部分 AB
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 105;
int T, n;
int dp[maxn][maxn];
char s[maxn];
bool match(int i, int j){ return (s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']'); }
void print(int i, int j){
if(i == j){
if(s[i] == '(' || s[i] == ')') printf("()");
else printf("[]");
return;
}
if(match(i, j) && (dp[i][j] == dp[i+1][j-1] + 2)) {
if(i+1 == j){
if(s[i] == '(') printf("()");
else printf("[]");
return;
}
if(s[i] == '('){
printf("(");
print(i + 1, j - 1);
printf(")");
} else{
printf("[");
print(i + 1, j - 1);
printf("]");
}
} else{
for(int k = i ; k < j ; ++k){
if(dp[i][k] + dp[k+1][j] == dp[i][j]){
print(i, k); print(k+1, j);
break;
}
}
}
}
void readline(char* S) {
fgets(S, maxn, stdin);
}
ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
int main(){
readline(s);
sscanf(s, "%d", &T);
readline(s);
int flag = 0;
while(T--){
readline(s);
n = strlen(s) - 1;
memset(dp, 0x3f, sizeof(dp));
for(int i = 0 ; i < n ; ++i){
dp[i][i] = 2;
dp[i+1][i] = 0;
}
for(int l = 2 ; l <= n ; ++l){
for(int i = 0 ; i + l - 1 < n ; ++i){
int j = i + l - 1;
if(match(i, j)) dp[i][j] = min(dp[i][j], dp[i+1][j-1] + 2); // '[][]'
for(int k = i ; k < j ; ++k){
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]);
}
}
}
print(0, n-1);
printf("\n");
if(T) printf("\n");
readline(s);
}
return 0;
}