题目大意:括号匹配问题,注意题目给的是子序列,而不是子串。
题解:区间DP,定义状态dp[l][r],表示从l到r匹配的最大对数。我们可以直接让l和r进行匹配(如果l和r可以匹配的话)那么dp[l][r]=dp[l+1][r-1]+2;或者dp[l][r]=dp[l][i]+dp[i+1][r],就是通过枚举区间来转移。
code:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; const int N=100+7; char s[N]; int dp[N][N]; int main(){ while(cin>>s+1){ memset(dp,0,sizeof dp); if(!strcmp(s+1,"end")) break; int n=strlen(s+1); for(int i=1;i<n;i++){ if(s[i]=='('&&s[i+1]==')') dp[i][i+1]=2; else if(s[i]=='['&&s[i+1]==']') dp[i][i+1]=2; } for(int len=3;len<=n;len++){ for(int l=1,r=len;r<=n;l++,r++){ if(s[l]=='('&&s[r]==')'||s[l]=='['&&s[r]==']') dp[l][r]=dp[l+1][r-1]+2; for(int i=l;i+1<=r;i++) dp[l][r]=max(dp[l][r],dp[l][i]+dp[i+1][r]); } } cout<<dp[1][n]<<endl; } return 0; }