括号匹配(二)
题目描述:
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
输入描述:
第一行输入一个正整数N,表示测试数据组数(N<=10) 每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出描述:
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入:
复制
4 [] ([])[] ((] ([)]
样例输出:
0 0 3 2
题意:找最小的数量能使所有括号匹配;
思路:区间dp[i][j] 代表着i-j的最少需求,把所以只剩自己在中间的dp[i][i]赋值1表示只需要一个就可以,然后i-j中每个小区间
i ~ k,k+1 ~ j一起查找最小就ok了;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MN = 150;
int dp[MN][MN];
char a[MN];
bool flag(char x,char y)
{
if ((x == '(' && y == ')') || (x == '[' && y == ']'))
return true;
return false;
}
int main()
{
int i, j, n, m;
while (~scanf("%d",&n))
{
while (n--)
{
scanf("%s",a);
int la = strlen(a);
memset(dp,0,sizeof(dp));
for (i = 0;i < la;i++) dp[i][i] = 1; //这里初始化的是自己独立时没有匹配的值;
for (int len = 1;len < la;len++) //len表示你要查的区间大小i~j;
{
for (i = 0;i < la - len;i++) //保证j不越界
{
j = i + len;
dp[i][j] = 99999999;//初始化最大
if (flag(a[i],a[j]))
dp[i][j] = dp[i+1][j-1]; //如果可以配对,i-j最小的需求就等于里面一层的
for (int k = i;k <= j;k++)//i-j中找最小的需求
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
printf("%d\n",dp[0][la-1]);
}
}
return 0;
}