对第一篇题解 (PassName & hanss6) 的补充
查看原帖
对第一篇题解 (PassName & hanss6) 的补充
51971
syksykCCCPAHs楼主2025/7/18 17:15

因为题解区没法发了,所以在讨论区和大家讨论一下对 PassName & hanss6 的这个题解 的看法,不是讨论区题解(

如果我的理解有误,真诚希望原作者 / 各位大佬批评指正

我认为这个做法(尤其是代码)相当巧妙,但是我在思考这个做法的过程中发现这个算法并非看上去那么容易,而且讨论区有诸多关于正确性的顾虑。实际上这个代码利用了很多 trick,作者对做法的叙述本身带有很强的迷惑性,比如 ai=ai1a_i = a_{i-1} 时实际上 lstai=i1lst_{a_i} = i-1,那么计算 fif_i 的时候就会调用 fif_i 本身

那这个会不会产生问题呢?并不会,因为已经赋值了 fi=fi1f_i = f_{i-1},这里实际上计算的是 fi1+ai\color{green}f_{i-1} + a_i。所以如果你“等价的”写作 fi=max(fi1,flstai+1+)f_i = \max(f_{i-1}, f_{lst_{a_i} + 1} + \cdots) 就会 WA。


接下来是形式化的解释。

首先明确 fif_i 的定义是 当前考虑 [1,i][1, i],与 aia_i 完全相同的末尾若干个数强制视作一段的开头,这种情况下的 [1,i][1, i] 的最佳收益。 比如 ai=7a_i = 7,那 fif_i 描述的分段就是形如

a1,a2,,aik,7,7,,ai=7a_1, a_2, \color{red}\cdots, a_{i-k}, \color{blue}7, 7, \cdots, a_i=7

我们解释程序的行为为什么符合这个描述。首先 ai=ai1a_i = a_{i-1} 时,最优方案肯定是 ii 继承 i1i-1 的颜色,所以程序的行为按照上面引言所述,就是 fi=fi1+ai\color{green}f_i = f_{i-1} + a_i

于是程序会把相同的一段数缩点,接下来不妨设相邻的两个数都是不同的。 fif_i 代表 ii 恰好是新一段的开头,i1i-1 是上一段的结尾

a1,a2,,ai1,aia_1, a_2, \color{red} \cdots, a_{i-1}, \color{blue} a_i

接下来就是评论区讨论最多的问题:为什么一定从 lstai+1lst_{a_i} + 1 处转移?(这里已经有 lstaii1lst_{a_i} \ne i-1

我们需要分别从最优方案 aia_i 产生贡献 / 不产生贡献两个角度来说明。

情况 1:如果 aia_i 产生贡献

那么与 aia_i 匹配的一定是 lstailst_{a_i} 处的值 ()(*)。画个图就是

a1,a2,,alst,alst+1,,ai1,aia_1, a_2, \color{blue}\cdots, a_{lst},\color{red} a_{lst + 1}, \cdots, a_{i-1}, \color{blue} a_i

所以转移需要用到的是 flst+1f_{lst \color{green}\bf+ 1},因为 ff 的下标是红色段的开头第一个数。

如若 ()(*) 不然,那就是搬出了古早相同值 aold=aia_{old} = a_i 进行匹配,我们作调整

a1,a2,,aold,,alst,,ai1,aia1,a2,,aold,,alst,,ai1,ai\begin{aligned} & a_1, a_2, \color{blue}\cdots, a_{old}, \color{red}\cdots, a_{lst}, \cdots, a_{i-1}, \color{blue} a_i\\ \Rightarrow & a_1, a_2, \color{blue}\cdots, a_{old}, \color{red}\cdots, \color{blue}a_{lst},\color{red} \cdots, a_{i-1}, \color{blue} a_i \end{aligned}

只改变 alsta_{lst} 的颜色,我们实现了收益增大。

情况 2:如果 aia_i 不产生贡献

那么 fi1f_{i-1} 就是我们需要的答案。这并不是特别 trivial,因为按照 fi1f_{i-1} 的定义我们需要 i1i-1 独立成段

a1,a2,,ai2,ai1,aia_1, a_2, \color{blue}\cdots, a_{i-2},\color{red} a_{i-1}, \color{blue}a_i

最优方案为什么一定是这样?我们再用调整法,假设上一个红色段很长

a1,a2,,aX,,ai2,ai1,aia1,a2,,aX,,ai2,ai1,ai\begin{aligned} & a_1, a_2, \color{blue}\cdots, a_{X},\color{red} \cdots, a_{i-2}, a_{i-1}, \color{blue} a_i\\ \Rightarrow & a_1, a_2, \color{blue}\cdots, a_{X},\color{red} \cdots, a_{i-2}, \color{blue} a_{i-1}, \color{red} a_i\\ \end{aligned}

这样答案不会下降,因为根据“不妨设”,有 ai2ai1a_{i-2} \ne a_{i-1},所以 ai1a_{i-1} 原先必没有贡献,而原先 aia_i 也没贡献,现在一调整,两者只会更好。所以 i1i-1 一定能独立成段。


最后一个我认为需要解答的点,是为什么这个顶一下,输出的答案是 fnf_n?实际上这个类比“情况 2”不难看出,ana_n 独立成段,一定是最优的。

2025/7/18 17:15
加载中...