2019暑假集训 括号匹配

 

题目描述
Hecy 又接了个新任务:BE 处理。BE 中有一类被称为 GBE。

以下是 GBE 的定义:

空表达式是 GBE
如果表达式 A 是 GBE,则 [A] 与 (A) 都是 GBE
如果 A 与 B 都是 GBE,那么 AB 是 GBE
下面给出一个 BE,求至少添加多少字符能使这个 BE 成为 GBE。
输入
输入仅一行,为字符串 BE。
输出
输出仅一个整数,表示增加的最少字符数。
样例输入
[])
样例输出
1
提示
对于100%的数据,输入的字符串长度小于100。

很明显是区间dp(和LCS问题类似)
按照区间dp的正常方法,我们不难发现,用dp[x][y]表示从x到y的区间已经匹配的字符数时,
(我不会说因为如果表示最少需增加括号数目我不会做的)从两个位置转移:
(1)因为A是GBE-------->[A]和(A)是GBE  则若x、y两个位置可以构成一对括号则dp[x][y]=dp[x+1][y-1]+2
(因为是两个已经匹配过的括号);
(2)因为A、B是GBE--------->AB是GBE  则枚举xy中区间断点k并用dp[x][k]+dp[k+1][y]更新dp[x][y];
所以我们得到了如下代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[105][105];
char str[1005];
int main()
{
    cin>>str+1;
    int len=strlen(str+1);
    for(int i=1;i<len;i++)
    {
        for(int j=1;j<=len-i;j++)
        {
            int l=j,r=j+i;
            if(str[l]=='('&&str[r]==')'||str[l]=='['&&str[r]==']')dp[l][r]=dp[l+1][r-1]+2;
            for(int k=l;k<r;k++)dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r]);
        }
    }
    printf("%d",len-dp[1][len]);//最后给所有没有匹配的再匹配即可
    return 0;
}
/*====年轻人,瞎搞是出不了省一的,这就是现实====*/
原文地址:https://www.cnblogs.com/qxds/p/11321620.html