您的位置:首页 > 其它

NYOJ 15 括号匹配(区间dp)

2017-07-22 15:26 399 查看
跟括号匹配(一)截然不同  二 不在考栈的应用了  这道题是一道区间dp 

这道题写了很久 自己没写出来 参考了网上超过15篇博客才算是略知一二

本文提供两种解法

方法一:

定义dp[i][j]  为从位置I到位置j所需要的括号数量  状态转移的过程是这样的  枚举I和j  或者长度 如果第I个点和第j个点匹配  那么 dp[i][j] 是不是应该等于min(dp[I][j], dp[I + 1][j - 1]) 呢

如果不匹配那么我们可以枚举I到j中间所有的点  尝试是否能松弛 其实是尝试能否减小dp[I][j]  类似于松弛的操作 对就是这样 值得注意的是边界问题 和 dp数组的初始化问题

单独的一个位置dp[i][I]应该初始化为多少呢 没错 初始化为1 需要一个额外的括号使之匹配  差不多这样 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;
int main()
{
int t, dp[maxn][maxn];
char str[maxn];
cin >> t ;
while ( t -- ) {
cin >> str ;
int length = strlen(str);
for (int i = 0; i < length; i ++) {
for (int j = 0; j < length ; j ++) {
if(i < j) dp[i][j] = inf;
else if (i == j)dp[i][j] = 1;
else dp[i][j] = 0;
}
}//len 不从0开始是因为枚举长度为0没有意义
for (int len = 1; len < length; len ++) {//len表示从i开始的一段长度为len的区间
for (int i = 0; i < length - len; i ++) {//i表示区间的起点
int j = len + i;//j表示区间的终止点
if(str[i] == '(' && str[j] == ')' || str[i] == '[' && str[j] == ']')
dp[i][j] = min(dp[i][j] , dp[i + 1][j - 1]);
for (int k = i; k < j; k ++)
dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k + 1][j]);
}
}
cout << dp[0][length - 1] << endl;
}
}


方法二 :如果我们能找到这一串括号中的最大匹配量 那么需要额外添加的括号就是长度减去最大匹配量

稍微更改下方法一的代码就能得到方法二的代码  建议先看懂方法一在看方法二

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;
int main()
{
int t, dp[maxn][maxn];
char str[maxn];
cin >> t ;
while ( t -- ) {
cin >> str ;
int length = strlen(str);
memset(dp , 0, sizeof(dp));
for (int len = 1; len < length ; len ++) {//len依旧枚举长度
for (int i = 0; i < length - len; i ++) {//i为起点
int j = len + i;//终点
if(str[i] == '(' && str[j] == ')' || str[i] == '[' && str[j] == ']')
dp[i][j] = dp[i + 1][j - 1] + 2;//如果匹配 那么当前区间的值肯定是一个较小的区间的值+2来的
for (int k = i; k < j; k ++)//松弛过程
dp[i][j] = max(dp[i][j] , dp[i][k] + dp[k + 1][j]);
}
}
cout << length - dp[0][length - 1] << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 NYOJ