题意就是问()和[]的最大匹配数目,很明显的区间dp。。
设dp[i][j]表示从第i个到第j个的最大匹配数目,可以得到状态转移方程dp[i][j]=max{dp[i][j],dp[i][k]+dp[k][j]} i<=k<j.看代码
#include<stdio.h>
#include<string.h>
char a[110];
int dp[110][110];
int main()
{
int x,i,j,t,flag,k;
while(1)
{
gets(a);
x=strlen (a);
if(x==3&&a[0]=='e'&&a[1]=='n'&&a[2]=='d') break;
memset(dp,0,sizeof(dp));
for(i=1; i<x; i++) //枚举区间长度
{
for(j=0; j<x-i; j++) //起始位置
{
t=j+i; //末位置
dp[j][t]=0;
if(a[j]=='('&&a[t]==')') dp[j][t]=dp[j][t]>(dp[j+1][t-1]+2)?dp[j][t]:(dp[j+1][t-1]+2);//若最外层两个符号匹配
if(a[j]=='['&&a[t]==']') dp[j][t]=dp[j][t]>(dp[j+1][t-1]+2)?dp[j][t]:(dp[j+1][t-1]+2);//同上
dp[j][t]=dp[j][t]>dp[j+1][t]? dp[j][t]: dp[j+1][t];//考虑([],[()
dp[j][t]=dp[j][t]>dp[j][t-1]? dp[j][t]: dp[j][t-1];// []) ,()]
for(k=j; k<t; k++) //状态转移方程
{
dp[j][t]=dp[j][t]>(dp[j][k]+dp[k+1][t])? dp[j][t]:(dp[j][k]+dp[k+1][t]);
}
}
}
printf("%d\n",dp[0][x-1]);
}
return 0;
}