思路: 不同于回文串,括号匹配时游标不能从两边向中间移动,而必须设置区间范围从头开始。因此设置k作为起始点和终点的分界点去求得最大值。
DP状态转移方程:注(dp[i + 1][j - 1] + 2不一定是最大,所以也要进行分割运算)
if (s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']') {
dp[i][j] = dp[i + 1][j - 1] + 2;
}
for (int k = i; k < j; k++) {
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
}
#include<iostream>
#include<string>
#define max(i,j) (i>j)?i:j
using namespace std;
int dp[105][105] = { 0 };
int main() {
string s;
int len;
while (1) {
cin >> s;
if (s == "end") {
break;
}
len = s.length();
for (int i = 0; i < len; i++) {
memset(dp[i], 0, sizeof(int)*len);
}
memset(dp, 0, sizeof(dp));
for (int d = 1; d <len; d++) { /*区间*/
for (int i = 0; i < len-d; i++) { /*起始点*/
int j = i + d; /*终点*/
if (s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']') {
dp[i][j] = dp[i + 1][j - 1] + 2;
}
for (int k = i; k < j; k++) {
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
}
}
}
cout << dp[0][len - 1] << endl;
}
return 0;
}