CF612F - Simba on the Circle 题解

这道题做的真是累死了……


显然,题目要求是要对于每一种数,依次输出所有等于这个值的位置,同一个值之间的输出顺序随便。

然后可以想到一个很自然的以数的值从小到大为阶段的 DP:\(dp_{i,j}\) 表示第 \(i\) 大的数值输出完后,停在 \(j\) 最小步数。这样 DP 值数量是 \(n^2\) 的,那么就意味着需要均摊 \(\mathrm O(1)\) 转移/jk。但实际上这事可实现的。

我们考虑如何转移。我们考虑从决策(也就是起点)\(k\) 跑到 \(j\),并且中途经过所有该输出的位置,的最小步数的走法。显然 \(j,k\) 把整个环分成两段,一段是 \(k\to j\) 顺时针走,一段是逆时针(这里我们可以把时针方向等价到线性结构上来理解,顺时针走就是加,逆时针就是减)。那不难想到最优路线一定是先解决一部分,然后绕另一部分走到 \(j\)。后者显然可以完整地经过对应部分,而前者只需要走到最后一个该输出的位置就可以改变方向了。于是把这两种情况各自算然后取个 \(\min\) 即可。

然后考虑其中一种情况怎么算(以先逆后顺为例)。我们考虑固定住 \(j\),那么 \(k\to j\) 的逆时针路线上的最后一个该输出的点显然只有两种可能:没有,或 \(j\) 的顺时针方向第一个。设「\(j\) 的顺时针方向第一个」为 \(p\)\(p\) 可以 two-pointers 算出来),我们考虑枚举 \(j,k,p\) 的相对位置,对于每种位置显然可以列出简单式,不带分段和绝对值的。到了这时候我们就应该拿出一整张空白的草稿纸,静下心来一类一类分类讨论,而不是一遍分类一边跟 hsc 聊天。

序号 $\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $ 式子 $\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $
\(1\) \(dp_{i-1,k}+n-(k-j)=(dp_{i-1,k}-k)+n+j\)
\(2\) \(dp_{i-1,k}+n-(p-j)+(k-p)=(dp_{i-1,k}+k)+n-(p-j)-p\)
\(3\) \(dp_{i-1,k}+2n-(j-k)-2(p-j)=(dp_{i-1,k}+k)+2n-j-2(p-j)\)
\(4\) \(dp_{i-1,k}+n-(k-j)=(dp_{i-1,k}-k)+n+j\)
\(5\) \(dp_{i-1,k}+(j-k)=(dp_{i-1,k}-k)+j\)
\(6\) \(dp_{i-1,k}+2(k-p)+(j-k)=(dp_{i-1,k}+k)-2p+j\)

其中前三类是 \(p>j\) 的情况,后三类是 \(p\leq j\),事实上只可能有一个得到满足,到时候 if else 一下即可。那么这样显然我们只需要维护区间 \(dp_{i-1,k}+k\)\(dp_{i-1,k}-k\) 的最小值。其中有四类是可以直接前后缀的,还剩两类需要单调队列(因为注意到 \(j,p\) 都单调且单调方向相同)。然后发现先顺后逆的情况,和上述六种情况是恰好成镜像的,把能反的都反过来(相对大小、式子里的符号、更新顺序),CV 然后改一改就好了。

然后最后还需要输出路径,就记录路径(不仅要记录转移对象,还要记录是先逆后顺还是先顺后逆)。非常难写。

code


上面我自己 yy 的方法非常难推且难写,码量 4k,我昨天晚上做了 2h,今天放学回来又做了 1h。

然后看到 ymx 的题解,得出一个结论:凡是烦一点的题,我一定是做的最麻烦的人。

ymx 的 DP 是一维的,他的 DP 状态可以等价理解为,我的状态加上这么一个优化:只可能停留在当前数值的位置,然后再开一个表示当前阶段的开始位置,也是只能开始于当前数值的位置。这样一来总状态数是线性的了。\(i-1\to i\) 的转移只需要暴力枚举转移对,然后 \(i\to i\)(也就是我的方法麻烦的主体)自然也可以暴力枚举了。至于说也要分个几类讨论一下路线,但显然是严格方便于我的方法的。我还要用 DS 维护,我枯了啊/kk

好好的一个 2600 题被我做成了这样,就当是练习了一下复杂的分类讨论能力吧(

题解也写吐了(

posted @ 2020-12-22 20:39  ycx060617  阅读(102)  评论(1编辑  收藏  举报