题解
题目大意 给一行括号进行配对 问这行括号的最大配对数量 (()也算是有一对匹配成功
使用区间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;
}