http://poj.org/problem?id=2955
【题意】 给出一串括号的字符串最长100, (), [], (()), ()[], ()[()] 是合法的
想这种 (, ], )(, ([)], ([(] 是不合法的 求出最长的 合法的 子序列
【思路】 d[i][j] 从i到j 的最长的
if (d[i][i+k]<d[i][t-1]+d[t+1][i+k-1]+2)
(d[i][i+k]<d[i][t-1]+d[t+1][i+k-1]+2
注意求d[i][j]的顺序 因为大区间依赖小区间所以按j-i 递增的顺序来求
具体的看代码
#include<iostream> #include<stdio.h> #include<string.h> #define INF 100000000 using namespace std; int d[102][102]; char s[102]; int ok(int x,int y) { if(s[x]==']'&&s[y]=='[') return 1; if(s[x]==')'&&s[y]=='(') return 1; return 0; } int main() { int i,j,m,t,k; while(~scanf("%s",s+1)) { if(strcmp(s+1,"end")==0) break; int n=strlen(s+1); //printf("s %s ",s); memset(d,0,sizeof(d)); for(k=1;k<=n;k++) for(i=1;i+k<=n;i++) { d[i][i+k]=d[i][i+k-1]; if(s[i+k]==']'||s[i+k]==')') for(t=i;t<i+k;t++) if(ok(i+k,t)&&d[i][i+k]<d[i][t-1]+d[t+1][i+k-1]+2) d[i][i+k]=d[i][t-1]+d[t+1][i+k-1]+2; //printf("& %d %d %d %c ",i,i+k,d[i][i+k],s[i+k]); } int ans=0; for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) if(ans<d[i][j]) ans=d[i][j]; printf("%d ",ans); } return 0; }