括号配对
题目描述:
Hecy 又接了个新任务:BE 处理。BE 中有一类被称为 GBE。
以下是 GBE 的定义:
空表达式是 GBE
如果表达式 A
是 GBE,则 [A]
与 (A)
都是 GBE
如果 A
与 B
都是 GBE,那么 AB
是 GBE
输入格式:
仅输入一行,为字符串BE
输出格式:
仅输出一个整数,表示增加的最少字符数
思路:
区间dp
为了方便转移,先预处理长度为1的区间和长度为2的区间
然后在转移的时候,如果合并的左区间的最后一个括号可以和右区间的第一个括号匹配,那么fij=min(fij,fik+fk+1,j-2),否则fij=min(fij,fik+fk+1,j),k为转移的中间点
然后如果合并的左区间的第一个括号可以和右区间的最后一个括号配对,那么fij=min(fij,fi+1,j-1)
CODE:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 #define MAXN 1010 7 char str[MAXN]; 8 int f[MAXN][MAXN]; 9 int i,j,k,m,n; 10 int main(){ 11 scanf("%s",str+1); 12 n=strlen(str+1); 13 for(i=1;i<=n;i++){ 14 f[i][i]=1; 15 } 16 for(i=1;i<=n-1;i++) 17 if((str[i]=='('&&str[i+1]==')')||(str[i]=='['&&str[i+1]==']')){ 18 f[i][i+1]=0; 19 }else{ 20 f[i][i+1]=2; 21 } 22 for(i=3;i<=n;i++){ 23 for(j=1;j<=n-i+1;j++){ 24 int t=j+i-1; 25 f[j][t]=1000000000; 26 for(k=j;k<t;k++){ 27 if((str[k]=='('&&str[k+1]==')')||(str[k]=='['&&str[k+1]==']')) f[j][t]=min(f[j][t],f[j][k]+f[k+1][t]-2); 28 else f[j][t]=min(f[j][t],f[j][k]+f[k+1][t]); 29 } 30 if((str[j]=='('&&str[t]==')')||(str[j]=='['&&str[t]==']')) f[j][t]=min(f[j][t],f[j+1][t-1]); 31 } 32 } 33 printf("%d\n",f[1][n]); 34 return 0; 35 }