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

括号匹配(二)




题目描述:

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

输入描述:

第一行输入一个正整数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;
}


猜你喜欢

转载自blog.csdn.net/clonh/article/details/80459895
今日推荐