括号最少匹配,比较经典的一个题。转移方程式跟矩阵相乘次最少数差不多。dp[i][j]=min(dp[i][k],dp[k+1][j]);
这个题需要注意的是输入,是一个空行一个数据的形式,并且输入可能有空串
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int inf=1<<29;
const int maxn=110;
char str[maxn];
int n,dp[maxn][maxn];
pair<int,int> pre[maxn][maxn];
bool check(int i,int j)
{
if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
return true;
return false;
}
void DFS(int l,int r)
{
if(l>r)
return;
if(l==r)
{
if(str[l]=='['||str[l]==']')
printf("[]");
if(str[l]=='('||str[l]==')')
printf("()");
return ;
}
if(check(l,r)&&dp[l][r]==dp[l+1][r-1])
{
printf("%c",str[l]);
DFS(l+1,r-1);
printf("%c",str[r]);
return;
}
int sl=pre[l][r].first;
int sr=pre[l][r].second;
DFS(sl,sr);
DFS(sr+1,r);
}
int main()
{
int T;
scanf("%d",&T);
getchar();
while(T--)
{
memset(pre,-1,sizeof(pre));
gets(str);
gets(str);
n=strlen(str);
for(int i=0;i<n;i++)
dp[i][i]=1;
for(int j=1;j<n;j++)
for(int i=0;i+j<n;i++)
{
dp[i][i+j]=inf;
if(check(i,i+j))
{
dp[i][i+j]=dp[i+1][i+j-1];
pre[i][i+j]=make_pair(i+1,i+j-1);
}
for(int k=0;k<=j;k++)
if(dp[i][i+j]>dp[i][i+k]+dp[i+k+1][i+j])
{
dp[i][i+j]=dp[i][i+k]+dp[i+k+1][i+j];
pre[i][i+j]=make_pair(i,i+k);
}
}
DFS(0,n-1);
printf("\n");
if(T)
printf("\n");
}
return 0;
}