区间dp经典 poj2955

来源:互联网 发布:linux chmod u s 编辑:程序博客网 时间:2024/05/31 18:50

从左到右 凡是 先遇到 '(' 后遇到‘)’  或者 先遇到 '[‘ 后遇到 ’]'的算一个匹配 长度为2


假设一个串 长度为  len

0.....................(len-1)

求 其中 任意 i 到 j 下标 的 子串 它 的 最长 匹配括号长度 
设为 f(i,j)

则 f(i,j)=max( f[i,k]+f[k+1][j](枚举) , f[i+1][j-1]+(a[i],a[j]是否匹配?2:0));


ok 动态归划  从 子状态 开始 推

则 边界是 len=1和 len=2的 时候 其dp值 分别为 0 和 2或0

#include <iostream>#include <string.h>#include <cstring>#define Max(a,b) (a)>(b)?(a):(b)using namespace std;const int MAXN=110;char str[MAXN];int dp[MAXN][MAXN];bool Is_Match(const char &a,const char &b){if(a=='(' && b==')')  return true;if(a=='[' && b==']')  return true;return false;}int main(void){while(cin>>str){if(str[0]=='e')  break;int i,j,k;int len=strlen(str);memset(dp,0,sizeof(dp));for (i = 0; i < len; i++) {dp[i][i] = 0;if(Is_Match(str[i],str[i+1]))  dp[i][i+1]=2;                           //len=1和 len=2的 时候 其dp值 分别为 0 和 2或0else  dp[i][i+1]=0;}for (k = 3; k <= len; k++) {for( i = 0; i+k-1 < len; i++) {if(Is_Match(str[i],str[i+k-1]))  dp[i][i+k-1]=dp[i+1][i+k-2]+2;for (j = i; j < i+k-1; j++) {dp[i][i+k-1]=Max(dp[i][i+k-1],dp[i][j]+dp[j+1][i+k-1]);}}}cout<<dp[0][len-1]<<endl;}return 0;}


原创粉丝点击