从左到右 凡是 先遇到 '(' 后遇到‘)’ 或者 先遇到 '[‘ 后遇到 ’]'的算一个匹配 长度为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; }