题目链接

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

输入
第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100

输出
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行

样例输入
4
[]
([])[]
((]
([)]

样例输出
0
0
3
2

分析:
首先,这个问题具体是很经典的区间动态规划问题,那么,我们可以使用一个二维数组dp[i][j] 表示字符串s的第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<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
char ch[109];
int dp[109][109];///dp[i][j]表示的是从第i个字符到第j个字符,想要匹配需要添加的字符数
bool cmp(char a,char b)///看字符a和字符b是否匹配
{
    if((a=='('&&b==')')||(a=='['&&b==']'))
        return true;
    return false;
}
void solve(int len)
{
    memset(dp,0,sizeof(dp));
    for(int i=0; i<len; i++) ///自己到自己如果想要匹配的话,肯定都得添加一个
        dp[i][i]=1;
    for(int w=1; w<len; w++)///控制的是字符匹配的间距
    {
        for(int i=0; i<len-w; i++)///开始的字符
        {
            int j=i+w;///表示的是结束字符的下标
            dp[i][j]=0x3f3f3f3f;
            if(cmp(ch[i],ch[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]);
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",ch);
        int k=strlen(ch);
        solve(k);
    }
}
posted on 2017-07-20 08:45  渡……  阅读(304)  评论(0编辑  收藏  举报