POJ - 2955 括号 (区间DP)
分析:区间DP的典型题,设dp[i][j]为i到j的最大匹配数
依次从小到大的区间进行更新
如果a[i]==a[j]那么产生新的匹配,dp[i][j]=max(dp[i][j],dp[i+1][j-1]+1)
再依次枚举断点从原先得到的匹配区间中转移,找最大值
dp[i][j]=max(dp[i][j],dp[i][i+k]+dp[i+k+1][j]);
代码如下:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; char str[150]; int dp[150][150]; int maxx; bool check(char x,char y) { if(x=='('&&y==')') return true; if(x=='['&&y==']') return true; return false; } int main() { while(scanf("%s",str+1)!=EOF) { memset(dp,0,sizeof(dp)); maxx=0; int len=strlen(str+1); if(str[1]=='e') break; for(int i=1;i<len;i++) { if(check(str[i],str[i+1])) { dp[i][i+1]=1; } } for(int l=2;l<=len-1;l+=1) { for(int i=1;i<=len-l;i++) { int j=i+l; if(check(str[i],str[j])) dp[i][j]=max(dp[i][j],dp[i+1][j-1]+1); for(int k=0;i+k<j;k++) dp[i][j]=max(dp[i][j],dp[i][i+k]+dp[i+k+1][j]); maxx=max(dp[i][j],maxx); } } printf("%d\n",maxx*2); } return 0; }