设串s至少需要增加d[s]个括号:
1.若s形如(s’)则d[s] 可转移为d[s’];
2.若s由至少两个字符组成,则可以把S分为A,B两个部分d[s] = d[A] +d[B];
边界:S为空时d[s] = 0,S为一个字符时d[s] = 1;
注意:一个串在进行第一个处理后还要进行第二个处理。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <cmath>
using namespace std;
int dp[105][105];
string s;
int match(char s1, char s2)
{
if((s1 == '(' && s2 == ')') || (s1 == '[' && s2 == ']'))
return 1;
return 0;
}
void print(int s1, int s2)
{
if(s1 > s2)return ;
if(s1 == s2){
if(s[s1] == '(' || s[s1] == ')')
cout << "()";
else
cout << "[]";
return ;
}
int ans = dp[s1][s2];
if(match(s[s1], s[s2]) && ans == dp[s1+1][s2-1])
{
cout << s[s1];
print(s1+1, s2-1);
cout << s[s2];
return ;
}
for(int k = s1; k < s2; k++)
{
if(dp[s1][k] + dp[k+1][s2] == ans)
{
print(s1, k);
print(k+1, s2);
return ;
}
}
}
int main()
{
// freopen("in.txt", "r", stdin);
int t;
cin >> t;
getchar();
while(t--)
{
getchar();
getline(cin, s);
int n = s.size();
for(int i = 0; i < n; i++)
{
dp[i][i] = 1;
dp[i+1][i] = 0;
}
for(int i = n - 2; i >= 0; i--)
for(int j = i+1; j < n; j++)
{
dp[i][j] = n;
if(match(s[i], s[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]);
}
print(0, n - 1);
cout << endl;
if(t)
cout << endl;
}
return 0;
}