从左到右 凡是 先遇到 '(' 后遇到‘)’ 或者 先遇到 '[‘ 后遇到 ’]'的算一个匹配 长度为2
假设一个串 长度为 len
0.....................(len-1)
求 其中 任意 i 到 j 下标 的 子串 它 的 最长 匹配括号长度
设为 f(i,j)
则 f(i,j)=max( f[i,k]+f[k+1][j](枚举) , f[i+1][j-1]+(a[i],a[j]是否匹配?2:0));
ok 动态归划 从 子状态 开始 推
则 边界是 len=1和 len=2的 时候 其dp值 分别为 0 和 2或0
#include <iostream>
#include <string.h>
#include <cstring>
#define Max(a,b) (a)>(b)?(a):(b)
using namespace std;
const int MAXN=110;
char str[MAXN];
int dp[MAXN][MAXN];
bool Is_Match(const char &a,const char &b){
if(a=='(' && b==')')
return true;
if(a=='[' && b==']')
return true;
return false;
}
int main(void)
{
while(cin>>str)
{
if(str[0]=='e')
break;
int i,j,k;
int len=strlen(str);
memset(dp,0,sizeof(dp));
for (i = 0; i < len; i++) {
dp[i][i] = 0;
if(Is_Match(str[i],str[i+1]))
dp[i][i+1]=2; //len=1和 len=2的 时候 其dp值 分别为 0 和 2或0
else
dp[i][i+1]=0;
}
for (k = 3; k <= len; k++) {
for( i = 0; i+k-1 < len; i++) {
if(Is_Match(str[i],str[i+k-1]))
dp[i][i+k-1]=dp[i+1][i+k-2]+2;
for (j = i; j < i+k-1; j++) {
dp[i][i+k-1]=Max(dp[i][i+k-1],dp[i][j]+dp[j+1][i+k-1]);
}
}
}
cout<<dp[0][len-1]<<endl;
}
return 0;
}