C: 括号序列
时间限制: 1 Sec 内存限制: 128 MB
题目描述
定义如下规则序列(字符串):
1.空序列是规则序列;
2.如果S是规则序列,那(S)和[S]也是规则序列;
3.如果A和B都是规则序列,那么AB也是规则序列。
例如,下面的字符串都是规则序列:
(), [], (()), ([]), ()[], ()[()]
这几个不是规则序列:
(, [, ], )(, ([()
现在,给出一些有'(' , ')' , '[' , ']'组成的序列,请添加尽量少的括号,得到一个规则序列,并输出该序列的长度。
输入
输入一个有'(' , ')' , '[' , ']'组成的序列,长度不超过200
输出
输出规则后的字串长度
样例输入
([(]
样例输出
6
提示
([()])//6
Solution
这道题目我一开始觉得想最长公共子序列,就像先求匹配的最大长度
方程是这样的:f[i][j]=f[i+1][j-1]+2 (a[i],a[j]匹配)
F[i][j]=max(f[i+1][j],f[i][j-1]) (a[i],a[j]不匹配)
然而这是错的,比如 [][] 这种数据
标解是这样的:
令f[i][j]为i到j括号匹配的最大数目
状态转移方程:f[i][j]=max{f[i][k]+f[k+1][j]} (i<=k<=j-1)
F[i][j]=max{f[i][j],f[i+1][j-1]+2} (a[i],a[j]匹配)
当然,匹配时上面的式子也要算一遍
特别注意:当然,匹配时上面的式子也要算一遍
意思是if (s[i]==s[i])F[i][j]=max{f[i][j],f[i+1][j-1]+2}
之后不能接else,应该直接上for循环,不能少!!!
不然我第一种想法的反例( [][] )就是一个反例!!
#include<bits/stdc++.h>
using namespace std;
#define MAXN 210
char str[MAXN];
int f[MAXN][MAXN];
int len_str;
bool pd(char x,char y)
{
if (x=='(' && y==')') return true;
if (x=='[' && y==']') return true;
return false;
}
int main()
{
scanf("%s",str+1);
len_str=strlen(str+1);
for (int len=2;len<=len_str;len++)
for (int i=1;i<=len_str-len+1;i++)
{
int j=i+len-1;
if (pd(str[i],str[j]))
f[i][j]=f[i+1][j-1]+2;
for (int k=i;k<j;k++)
f[i][j]=max(f[i][k]+f[k+1][j],f[i][j]);
}
printf("%d",len_str+(len_str-f[1][len_str]));
return 0;
}
第二种解法:
F[i][j]表示需要加的最小的括号数量
F[i][j]=min{f[i][k]+f[k+1][j]} (i<=k<=j-1)
F[i][j]=min{f[i][j],f[i+1][j-1]} (a[i],a[j] 匹配)
注意这种解法的初始值是 无穷大oo
#include<bits/stdc++.h> using namespace std; #define MAXN 210 char str[MAXN]; int f[MAXN][MAXN]; int len_str; bool pd(char x,char y) { if (x=='(' && y==')') return true; if (x=='[' && y==']') return true; return false; } int main() { scanf("%s",str+1); len_str=strlen(str+1); memset(f,0x3f,sizeof(f)); for (int len=0;len<=len_str;len++) for (int i=1;i<=len_str-len+1;i++) { int j=i+len-1; if (len==0) { f[i][j]=0; continue; } if (len==1) { f[i][j]=1; continue; } if (pd(str[i],str[j])) f[i][j]=f[i+1][j-1]; for (int k=i;k<j;k++) f[i][j]=min(f[i][k]+f[k+1][j],f[i][j]); } printf("%d",len_str+f[1][len_str]); return 0; }