您的位置:首页 > 其它

NYOJ 15 括号匹配(二)(区间dp)

2016-08-03 11:15 274 查看

括号匹配(二)

时间限制: 1000 ms | 内存限制: 65535 KB

难度: 6

描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。

如:

[]是匹配的

([])[]是匹配的

((]是不匹配的

([)]是不匹配的
输入第一行输入一个正整数N,表示测试数据组数(N<=10)

每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100 输出对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行样例输入
4
[]
([])[]
((]
([)]


思路 : 本来以为只是个小模拟,没想到是个区间DP,还是对DP不了解。

DP[i][j]代表着从字符串 i 位置到 j 位置需要的最小括号匹配。

所以初始化的DP[i][i] = 1 ;第i个位置的话需要匹配的最小括号数是1。

状态转移方程 :如果第i个位置和第j个位置的两个括号是匹配的,那么DP[i][j] = DP[i+1][j-1],相当于两边分别往里缩了一个;当i < j 时,DP[i][j] = DP[i][k]+DP[k+1][j] ;

#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int const inf = 1000;
int const MAX = 1005;
int main()
{
int N;
cin >> N;
while(N--){
char s[MAX];
int dp[MAX][MAX];
cin >> s;
int len = strlen(s);
for(int i = 0; i < len; i++)
for(int j = 0; j < len; j++){
if(i < j)
dp[i][j] = inf;
else if(i==j)
dp[i][j] = 1;
else   dp[i][j] = 0;
}
for(int l = 1; l < len; l++){//线段长度递推
for(int i = 0; i < len - l; i++){
int j = i + l;
if((s[i]=='[' && s[j]==']') || (s[i]=='(' && s[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][len-1] << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: