经典的区间DP
dp[i][j]代表i->j区间内最多的合法括号数
状态转移方程:
if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']') dp[i][j]=dp[i+1][j-1]+2;dp[i][j]=max{dp[i][k]+dp[k+1][j]};
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <set> #include <list> #include <queue> #include <map> #include <stack> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-3 #define maxn 100010 #define MOD 1000000007 int n,m; int dp[110][110]; char s[110]; int main() { int t,C = 1; while(scanf("%s",s) && strcmp(s,"end")) { memset(dp,0,sizeof(dp)); int len = strlen(s); for(int k = 1; k < len; k++) for(int i = 0; i + k < len; i++) { int j = k+i; if(s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']') dp[i][j] = dp[i+1][j-1] + 2; for(int p = i; p < j; p++) dp[i][j] = max(dp[i][j],dp[i][p]+dp[p+1][j]); } printf("%d\n",dp[0][len-1]); } return 0; }