版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ronaldo7_ZYB/article/details/83117069
最长括号匹配
这道题目看似可以使用栈来做,实则用DP可以更加简单。
我们设
为以第i位结尾的可以匹配的最大长度。
对于每一个第
位,如果需要存在合法序列必须满足两个条件
1.是左括号
2.必须和其有边的字符组成一个序列
事实上对于第一个条件我们只要简单的判断,而对于第二个条件就和我们的决策有关。
而对于转移方程f[i],只要当前的这个字符
和以
位起点构成串的有边匹配,就说明能够成立一个合法的串。如果列出转移方程,就是:
对于条件3,我们只要继续累加
即可。
CODE
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2000000
int MAX=0,st=0,f[MAXN];
char s[MAXN];;
int main()
{
cin>>s;
int len=strlen(s);
for (int i=len-1;i>=0;--i)
{
if (s[i]==')' || s[i]==']') continue;//右括号不合法
if ((s[i]=='(' && s[i+f[i+1]+1]==')') || (s[i]=='[' && s[i+f[i+1]+1]==']'))//存在对顶的字符串
{
f[i]=f[i+1]+2;//上一个决策加上新的收尾
f[i]+=f[i+f[i]];//满足条件3,即多个不同的串进行累加
if (f[i]>=MAX) MAX=f[i],st=i;
}
}
for (int i=0;i<MAX;i++) cout<<s[st+i];
return 0;
}