poj 2955

区间dp,给一个括号序列,求最长的合法的子序列的长度。
dp[i][j]表示[i,j]这段区间里面的最长子序列的长度,当s[i] =s[j] 是,可以转换位子问题:求[i+1,j-1]的最长合法子序列的长度,但是不能就直接求得,如 [][] , 可知答案应为4,但如果直接求得话就是2。
所以不管s[i] 和s[j] 是否相等,都要枚举中间得元素。
区间dp写成记忆化得时候一定要处理好边界情况。

#include <cstdio>
#include <cstring>
#include <algorithm> 

using namespace std;
char a[110];
int len,d[101][101];

bool match(int i,int j){
	return ((a[i]=='('&&a[j]==')')||(a[i]=='['&&a[j]==']'));
}
int dp(int i,int j){
	int & ans = d[i][j];
	if(ans != 1e9) return ans;
	if(i+1 == j) return (ans = match(i,j)?2:0);
	ans = 0;
	if(match(i,j)) ans = max(ans,dp(i+1,j-1)+2); 
	for(int k = i;k<j;k++)
		ans = max(ans,dp(i,k)+dp(k+1,j));
	return ans;
}

int main(){
	while(scanf("%s",a)&&strcmp(a,"end")){
		len = strlen(a);
		for(int i = 0;i<len;i++) for(int j = 0;j<len;j++) d[i][j] = 1e9;
		printf("%d\n",dp(0,len-1)); 
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/winhcc/article/details/88800510