题目链接:https://uva.onlinejudge.org/external/16/1626.pdf
题意: 给定一个字符串,看是否括号匹配,不匹配加括号,加最少的括号使得匹配。输出该结果。
分析: 解题思路和切木棍很类似。d(i,j) i ~ j 要加最少多少括号,他一定等于: 分两种情况,一:[s'],(s'),d(i,j) = d(i+1,j-1);二: d(i,j) = min(d(i,k),d(k+1,j));
注意: 输入有空行。

#include <bits/stdc++.h> using namespace std; const int maxn = 100+5; char S[maxn]; int n,d[maxn][maxn]; bool match(char a,char b) { return (a=='('&&b==')')||(a=='['&&b==']'); } void readline(char *S) { fgets(S,maxn,stdin); } int dp(int i,int j) { if(i>j) return 0; if(i==j) return 1; int& ans = d[i][j]; if(ans>=0) return ans; ans = n; if(match(S[i],S[j])) ans = min(ans,dp(i+1,j-1)); for(int k=i; k<j; k++) { ans = min(ans,dp(i,k)+dp(k+1,j)); } return ans; } void print(int i,int j) { if(i>j) return ; if(i==j) { if(S[i]=='('||S[i]==')') printf("()"); else printf("[]"); return ; } int ans = dp(i,j); if(match(S[i],S[j])&&ans==dp(i+1,j-1)) { printf("%c",S[i]); print(i+1,j-1); printf("%c",S[j]); return; } for(int k=i; k<j; k++) { if(ans==dp(i,k)+dp(k+1,j)) { print(i,k); print(k+1,j); return ; } } } int main() { int T; readline(S); sscanf(S, "%d", &T); readline(S); while(T--) { readline(S); n = strlen(S) - 1; memset(d, -1, sizeof(d)); print(0, n-1); printf(" "); if(T) printf(" "); readline(S); } return 0; }