Brackets POJ - 2955 区间dp

题解

题目大意 给一行括号进行配对 问这行括号的最大配对数量 (()也算是有一对匹配成功

使用区间dp求解 d[i][j]表示从i到j范围内的括号配对数量
按照一般套路枚举区间长度和区间起点 再枚举区间中点取最大值合并两个区间
当d[i][j]的最外层括号s[i]与s[j]配对则通过内层+2转移过来 即
d[i][j] = max(d[i][j], d[i + 1][j - 1] + 2)
不用担心i + 1反而大于j - 1的情况 那样值为0不影响结果

AC代码

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int MAXN = 110;
char s[MAXN];
int d[MAXN][MAXN]; //i到j范围内括号是配对的

int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	while (scanf("%s", s + 1) != EOF, s[1] != 'e')
	{
		memset(d, 0, sizeof(d)); //单个括号不可能配对
		int N = strlen(s + 1);
		int ans = 0;
		for (int l = 2; l <= N; l++) //区间长度
			for (int i = 1; i + l - 1 <= N; i++) //区间起点
			{
				int j = i + l - 1; //区间终点
				for (int k = i; k < j; k++) //区间最值合并
					d[i][j] = max(d[i][j], d[i][k] + d[k + 1][j]);
				if (s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']') //最外层括号配对
					d[i][j] = max(d[i][j], d[i + 1][j - 1] + 2); //则从内部转移
				ans = max(ans, d[i][j]);
			}
		cout << ans << endl;
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/CaprYang/article/details/85218865