小委出发
题目大意:一个长度为n的字符串,由()[]{}组成。求最长的和谐字符串:我们对最长和谐字符串的定义就是每一个括号有一个性质相同的括号与之匹配,这两个括号中间要么为空,要么也是和谐的。几个连续的和谐串连在一起也是和谐的。
注释:k<=$5\cdot 10^6$
想法:开始的想法是dp,怎么dp呢?我们设定dp[i]表示以第i个点为最后一个点的最长和谐子串。显然我们只需要记录一下每一个dp值的对应的位置即可,但是不好写,特判有些多,我们用一种很强的方式来解决这个问题(鸣谢Edward♂Frog)。我们用栈维护。如何用栈进行维护呢?如果当前元素是左边的括号,我就将其扔进栈里。如果当前元素是右括号,我就将它和栈顶元素进行比较,如果它和栈顶元素可以匹配,我就将它们双双弹出栈,将这两个元素的下标记为true,如果不是,我就清空栈。最后,从一到k每一个数对应true或false。我们只需要求最长的true的序列。这样为什么是对的?如果当前元素和栈顶元素相等,那么证明他们之间的元素是一定满足条件后被弹出的。所以,我们将这两个元素标记后,对于每一个和谐子串都一定有一串连续的1。我们只需要求最长的连续的1即可......
最后,附上丑陋的代码......
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int v[];
char s[];
int a[];
int x[];
int dp[];
int main()
{
scanf("%s",s+);
int k=strlen(s+);
for(int i=;i<=k;i++)
{
if(s[i]=='(') a[i]=;
else if(s[i]=='[') a[i]=;
else if(s[i]=='{') a[i]=;
else if(s[i]=='}') a[i]=;
else if(s[i]==']') a[i]=;
else a[i]=;
}
int top=;
for(int i=;i<=k;i++)
{
if(a[i]<=)
{
x[++top]=i;
}
else
{
if(a[x[top]]+a[i]==)
{
v[x[top]]=;
v[i]=;
top--;
}
else top=;
}
}
for(int i=;i<=k;i++)
{
if(v[i])
{
dp[i]=max(dp[i],dp[i-]+);
}
}
int maxk=;
int maxn=-;
for(int i=;i<=k;i++)
{
if(dp[i]>maxn) maxn=dp[i],maxk=i;
}
for(int i=maxk-maxn+;i<=maxk;i++) printf("%c",s[i]);
}
小结:错误,最后维护可以用并查集,虽然没必要
未经博主允许,严禁转载