现在的位置: 首页 > 综合 > 正文

区间dp经典 poj2955

2013年09月09日 ⁄ 综合 ⁄ 共 924字 ⁄ 字号 评论关闭

从左到右 凡是 先遇到 '(' 后遇到‘)’  或者 先遇到 '[‘ 后遇到 ’]'的算一个匹配 长度为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或0
			else
			  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;
}

抱歉!评论已关闭.