Hecy 又接了个新任务:BE 处理。
BE 中有一类被称为 GBE。
以下是 GBE 的定义:
空表达式是 GBE
如果表达式 A 是 GBE,则 [A] 与 (A) 都是 GBE
如果 A 与 B 都是 GBE,那么 AB 是 GBE
下面给出一个 BE,求至少添加多少字符能使这个 BE 成为 GBE。
注意:BE 是一个仅由(、)、[、]四种字符中的若干种构成的字符串。
输入格式
输入仅一行,为字符串 BE。
输出格式
输出仅一个整数,表示增加的最少字符数。
数据范围
对于所有输入字符串,其长度小于100。
输入样例:
[])
输出样例:
1
从当前BE变成GBE需要添加最少字符的数量 等价于 当前Be变成最大的GBE
需要去掉字符的数量
即至少添加最少字符 等价于 总数量 - 最大GBE子序列的长度
注意:这题和密码脱落也有些不同,GBE有回文的性质 或者 有另外一种
性质,例如[]() , ([])均是GBE,因此需要对s[L] 和 s[R]不匹配的
情况需要进一步划分,划分方式和石子合并类似
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110, INF = 100000000;
int n;
int f[N][N];
bool is_match(char l, char r)
{
if (l == '(' && r == ')') return true;
if (l == '[' && r == ']') return true;
return false;
}
int main()
{
string s;
cin >> s;
n = s.size();
for (int len = 1; len <= n; len ++ )
for (int l = 0; l + len - 1 < n; l ++ ){
int r = l + len - 1;
f[l][r]=INF;
if(len==1)f[l][r]=1;
else{
if(is_match(s[l],s[r]))f[l][r]=min(f[l][r],f[l+1][r-1]);
if(r>=1)f[l][r]=min(f[l][r],min(f[l][r-1],f[l+1][r])+1);
for (int k = l; k < r; k ++ )
f[l][r] = min(f[l][r],f[l][k]+f[k+1][r]);
}
}
cout<<f[0][n-1]<<endl;
return 0;
}