2019暑假集训 括号匹配
题目描述
Hecy 又接了个新任务:BE 处理。BE 中有一类被称为 GBE。
以下是 GBE 的定义:
空表达式是 GBE
如果表达式 A 是 GBE,则 [A] 与 (A) 都是 GBE
如果 A 与 B 都是 GBE,那么 AB 是 GBE
下面给出一个 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; }
/*====年轻人,瞎搞是出不了省一的,这就是现实====*/