随笔 - 51  文章 - 0  评论 - 6  阅读 - 436

CF1693D题解

很妙的dp题。
首先肯定要想判断一个序列是否合法。
第一篇题解的结论太强了,蒟蒻只能想到dp
dpi,0 表示 ai 作为上升段末尾时,下降段末尾的最大值
dpi,1 表示 ai 作为下降段末尾时,上升段末尾的最小值

  • 起点:dpi,0=inf,dpi,1=inf(i>1),dp1,0=inf,dp1,1=inf
  • 转移:
    ai1 能接到上升段(即 dpi1,0inf),则 dpi,0dpi1,0(ai>ai1),dpi,1ai1(ai<dpi1,0)
    ai1 能接到下降段(即 dpi1,1inf),则 dpi,1dpi1,1(ai<ai1),dpi,0ai1(ai>dpi1,1)

那么暴力枚举子段,用上述 dp 即可做到 O(n3)

考虑优化,假设固定左端点,那么合法的右端点只能是一个前缀,右端点右移的时候进行转移,优化为 O(n2)

观察上面的 dp 转移,发现 dpi 只与 dpi1 有关,如果 dpi1 在上一个左端点和当前左端点的值相同,i 后面的值都不会变化,那么我们从后往前枚举左端点,记录右端点的最大值 mxr,如果发现某一处的 dpi 未发生变化,直接继承上一次的 mxr 就行了,这样看似还是 O(n2),但这个做法足以通过本题。

有一个很神奇的性质:
对于所有左端点,dpi,0dpi,1 都只有 4 种取值。
证明:
对于 i,找到 i 之前最大的 j 满足 aj>aj+1,那么 ajaj+1 中必有一个是下降段的末尾,也就是说 dpi,0=aj/aj+1/inf
如果不存在 jdpi,0=inf
对于 dpi,1 同理。

于是每个点都最多被更新 7 次,之后就再也不会变化,复杂度降为 O(n)

posted on   cool_tyl  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示