[ACM] 携程预赛第一场 括号匹配 (动态规划)

括号匹配

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 110   Accepted Submission(s) : 46

Font: Times New Roman | Verdana | Georgia

Font Size:  

Problem Description

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

Input

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

Output

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

Sample Input

4
[]
([])[]
((]
([)]

Sample Output

0
0
3
2

Source

CodingTrip - 携程编程大赛 (预赛第一场)

代码:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int maxn=250;
const int inf=0x7fffffff;
char str[maxn];
int dp[maxn][maxn],ps[maxn][maxn];
//dp[i][j]代表串从i到j需要添加几个字符才能合法,ps[i][j],记录的从i到j在哪里断成两部分
int len;

int main()
{
    int k;cin>>k;
    while(k--)
    {
        cin>>str;
        len=strlen(str);
        memset(dp,0,sizeof(dp));
        for(int i=0;i<len;i++)
            dp[i][i]=1;
        for(int k=1;k<len;k++)//区间从小到大
            for(int i=0;i+k<len;i++)
        {
            int j=i+k;
            dp[i][j]=inf;
            if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
            {
                dp[i][j]=dp[i+1][j-1];
                ps[i][j]=-1;//括号匹配,不用添加另外的括号
            }
            for(int mid=i;mid<j;mid++)//看是否能划分为两部分
            {
                if(dp[i][j]>(dp[i][mid]+dp[mid+1][j]))
                {
                    dp[i][j]=dp[i][mid]+dp[mid+1][j];
                    ps[i][j]=mid;//mid为串i到j区间断开的位置
                }
            }
        }
        cout<<dp[0][len-1]<<endl;
    }
    return 0;
}


 

原文地址:https://www.cnblogs.com/sr1993/p/3697754.html