括号匹配(二) (动态规划)

括号匹配(二)

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

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

如:

[]是匹配的

([])[]是匹配的

((]是不匹配的

([)]是不匹配的

输入
第一行输入一个正整数N,表示测试数据组数(N<=10)

每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100

输出
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入
4
[]
([])[]
((]
([)]
样例输出
0
0
3

2

这是一个动态规划题目,解决问题的关键在于寻找dp[i][j]代表什么,还有递推公式是什么。

首先来说,对于任何一个字符串,需要从前到后计算其对应的答案,那么简单来说,i一定是从0~len-1

对于单个字符dp的值为1,很显然啊

对于两个字符还说,如果两个括号正好对应的话为0,不对应dp+1;

则对应的dp[i][j]表示从i到j对应当答案

当i= j的时候,只有一个字符,那么,只要匹配一个字符就行了,所以,dp[i][i] = 1

如果,当i < j的时候,s[i] = s[j]  那么,dp[i][j] = min(dp[i][j],dp[i+1][j-1]),其中,假设i <= k < j 状态转移方程为 dp[i][j] = min(dp[i][j],d[i][k] + dp[k+1][j])

#include <bits/stdc++.h>
using namespace std;
#define MAX 105

int dp[MAX][MAX];

int link(char a, char b)
{
	if((a=='(' && b==')')||(a=='['&&b==']')) return 1;
	else return 0;
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		string str;
		cin >> str;
		int len = str.size();
		for(int i = 0; i < len; i++)
		{
			dp[i][i] = 1;
		}
		for(int m = 1; m < len; m++)
		{
			for(int i = 0; i+m < len; i++)
			{
				int j = i+m;
				dp[i][j] = MAX;
				if(link(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]);
				}
			}
		}
		printf("%d\n", dp[0][len-1]);
	}
	return 0;
}

这个题目理解起来不是很难,但是第一遍的写的时候出现了一个bug,怎么调都挑不出来很神奇

    原文作者:括号匹配问题
    原文地址: https://blog.csdn.net/yinghui_yht/article/details/79671733
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞