bracket sequence (interval dp)
Enter a sequence consisting of "(", ")", "[", ")" whose length does not exceed 100. Please add as few brackets as possible to get a regular bracket sequence. If there are multiple solutions, output any sequence.
A bracket sequence is defined like this:
- An empty sequence is a bracketed sequence
- If S is a bracket sequence, then (S) and [S] are also regular bracket sequences
- If both A and B are regular bracket sequences, then AB is also a regular bracket sequence.
So, as long as a sequence of parentheses is not an empty sequence, we can certainly strip it from both ends, or divide it into two sequences of parentheses. Let \(f[i][j]\) mean that the string \(s[i][j]\) needs to add at least a few parentheses, then \(f[i][j]\) must be transferred to \ (f[i][k]+f[k][j]\) . If \(s[i]=s[j]\) , then you can also move to \(f[i+1][j-1]\) .
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=105;
int T, f[maxn][maxn], n;
char s[maxn];
//函数能使语义更清晰
bool match(int x, int y){ return s[y]-s[x]>0&&s[y]-s[x]<=2; }
void print(int l, int r){ //[l,r]
if (l>r) return;
if (l==r){
if (s[l]=='('||s[l]==')') printf("()");
else printf("[]"); return; }
int ans=f[l][r];
if (match(l, r)&&f[l+1][r-1]==ans){
putchar(s[l]); print(l+1, r-1); putchar(s[r]);
return; }
for (int k=l; k<r; ++k)
if (f[l][k]+f[k+1][r]==ans){
print(l, k); print(k+1, r); return; }
}
int main(){
scanf("%d", &T);
while (T--){
fgets(s, maxn, stdin);
fgets(s, maxn, stdin);
n=strlen(s)-1;
for (int i=0; i<n; ++i) f[i+1][i]=0, f[i][i]=1;
for (int i=n-2; i>=0; --i)
for (int j=i+1; j<n; ++j){
f[i][j]=n;
if (match(i, j)) f[i][j]=f[i+1][j-1]; //[i,j]
for (int k=i; k<j; ++k)
f[i][j]=min(f[i][j], f[i][k]+f[k+1][j]);
}
print(0, n-1); puts("");
}
return 0; //忘记return 0了!!
}