nyoj 15 括号匹配 (dp)

来源:互联网 发布:js懒加载的原理 编辑:程序博客网 时间:2024/05/11 05:56

括号匹配(二)

时间限制:1000 ms  |  内存限制:65535 KB
难度:6
描述
给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:
[]是匹配的
([])[]是匹配的
((]是不匹配的
([)]是不匹配的
输入
第一行输入一个正整数N,表示测试数据组数(N<=10)
每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100
输出
对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。每组测试输出占一行
样例输入
4[]([])[]((]([)]
样例输出
0032

分析:

主要思想就是将原问题化成子问题。

设dp[i][j]为第i个位置到第j个位置需要添加的符号数。设待判断字符串为s。从i开始寻找与s[j]相等的字符,位置设为k,即s[k]==s[j],i<=k<j。当找到时,dp[i][j]即为dp[i][j]和dp[i][k-1]+dp[k+1][j-1]中的小值。如果找不着,dp[i][j]=dp[i][j-1]+1。当i==j的时候,dp[i][j]=1。

 #include<stdio.h>#include<stack>#include<string.h>using namespace std;int pipei(char a,char b){    if(a=='('&&b==')')        return true;    if(a=='['&&b==']')        return true;    return false;}int main(){    int n,i,j,k,dp[102][102];    char a[1100];    scanf("%d",&n);    while(n--)    {        scanf("%s",a);        int s=strlen(a);        for(i=0; i<=s; i++)            dp[i][i]=1;//自己和自己配对,为1        for(i=2; i<=s; i++) //从边界向内循环判断        {            for(j=i-1; j>=1; j--)           {               dp[j][i]=dp[j][i-1]+1;   //如果不匹配的话加1就匹配            for(k=j; k<i; k++)                if(pipei(a[k-1],a[i-1]))  //如果两个字符匹配的话                    dp[j][i]=min(dp[j][k-1]+dp[k+1][i-1],dp[j][i]);        }        }        printf("%d\n",dp[1][s]);//输出1到s之间的匹配数目    }     return 0;}        


0 0