解题思路:
区间dp问题,dp[i][j]表示只考虑区间[i,j]时的最长满足条件的序列的长度。从长度为2的序列开始遍历,如果(s[i]’(’&&s[j]’)’)||(s[i]’[’&&s[j]’]’)成立则dp[i][j]=dp[i+1][j-1]+2,这是将s[i]和s[j]组成一组的情况,否则dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]),其中i<=k<=j,这是不将s[i]和s[j]组成一组的情况。
参考代码:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
string s;
int dp[105][105];
int main(int argc, const char * argv[]) {
while (cin>>s) {
if(s=="end")break;
memset(dp, 0, sizeof(dp));
int len=(int)s.length();
int cur_len=2;int j=0;
while (cur_len<=len) {
for (int i=0; i<=len-cur_len; i++) {
j=i+cur_len-1;
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]=dp[i][j]>dp[i][k]+dp[k][j]?dp[i][j]:dp[i][k]+dp[k][j];
}
}
cur_len++;
}
cout<<dp[0][len-1]<<endl;
}
return 0;
}