1 条题解
-
0
自动搬运
来自洛谷,原作者为

OItby
AFO.搬运于
2025-08-24 21:32:11,当前版本为作者最后更新于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; }
- 1
信息
- ID
- 911
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者