OItby
2020-03-04 21:42:37
对于这题
最长,可见这是道最值问题
最值问题可以用贪心,
我对于这题用的是太弱了,只会DP
进入正题:如何
首先,我们需要构建状态,状态的构建不是唯一的,受最长上升子序列(好题废话)的影响,我是这样构建的
令
接下来,我们就得推状态转移方程
考虑(
或者[
那么)
或者]
时我们应该怎样转移呢?
我们要找到一个(
(或者[
,为了方便叙述,下同),使得在
那么什么情况能满足上面的条件呢?
说明一下
那么若
分析千万条,代码第一条,不懂的看一下代码(懂得可以自己打去了,偷笑)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
const int L=1000005;
char s[L];
int l,f[L],Ans,id;
int main()
{
scanf("%s",s+1);//输入,下标从1开始
l=strlen(s+1);//下标从1开始的字符串长度
for(int i=2;i<=l;++i)//s[1]显然无法匹配,所以从2开始
if(s[i]=='('||s[i]=='[') continue;//如分析
else
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-1]-2];
if(f[i]>Ans) Ans=f[i],id=i;//Ans记录最长括号匹配,id记录最长括号匹配的下标
}
for(int i=id-Ans+1;i<=id;++i) printf("%c",s[i]);
putchar('\n');
return 0;
}