1 条题解

  • 0
    @ 2026-9-3 11:13:39

    题解

    思路

    把耐久度乘二,记 Li=2diL_i=2d_i。若最终保留的相邻三根柱子下标为 a,i,ba,i,b,中间普通柱 ii 能留下当且仅当

    xb−xa≤Li.x_b-x_a\le L_i.

    因此,只要存在一个满足所有三元限制的非空普通柱序列,它就不会被删除,最终状态也一定非空。新增柱子的最近左右邻居若为 i,ji,j,它所需的两倍耐久度恰为 xj−xix_j-x_i,与它在区间内的具体位置无关。

    做法

    下面给出从完全枚举、二次动态规划到满分数据结构优化的三档递进算法。

    算法一:子集穷举

    当 n≤14n\le14 时,枚举最终保留的原普通柱集合。对每个有序保留序列,先检查它能否单独稳定;再枚举新增柱子插入在哪两个相邻保留柱之间。

    设插入间隙左右端点为 i,ji,j。除这两个端点外,其他保留柱的左右邻居已经确定,可以直接检查。新增坐标 yy 还需满足:若 ii 为普通柱,则 y≤xpre⁡(i)+Liy\le x_{\operatorname{pre}(i)}+L_i;若 jj 为普通柱,则 y≥xnxt⁡(j)−Ljy\ge x_{\operatorname{nxt}(j)}-L_j。该区间与 [xi,xj][x_i,x_j] 有交集时,候选答案为 (xj−xi)/2(x_j-x_i)/2。

    正确性来自对所有可能最终保留集合和新增柱子所在间隙的完全枚举。

    复杂度为 O(2nn2)O(2^n n^2),空间复杂度为 O(n)O(n)。

    算法二:二次动态规划

    定义 fif_i 为:存在一条从左承重柱到 ii 的稳定链时,ii 右侧下一根柱子允许到达的最右坐标。令 f0=+∞f_0=+\infty。若 j<ij<i 是这条链中 ii 的前驱,则连接 jj 与 ii 必须满足 fj≥xif_j\ge x_i,且 ii 允许的下一坐标为 xj+Lix_j+L_i。因为坐标递增,只需选择最大的可行 jj:

    fi=xmax⁡{j<i∣fj≥xi}+Li.f_i=x_{\max\{j<i\mid f_j\ge x_i\}}+L_i.

    对称地从右向左定义 gig_i,表示 ii 左侧上一根柱子允许到达的最左坐标:

    gi=xmin⁡{j>i∣gj≤xi}−Li,g_i=x_{\min\{j>i\mid g_j\le x_i\}}-L_i,

    其中 gn+1=−∞g_{n+1}=-\infty。

    原建筑稳定当且仅当某个 fi≥xn+1f_i\ge x_{n+1}。否则枚举新增柱子的左右邻居 i<ji<j。可行条件为

    fi≥xi,gj≤xj,fi≥gj.f_i\ge x_i,\qquad g_j\le x_j,\qquad f_i\ge g_j.

    满足条件时更新 xj−xix_j-x_i。直接扫描转移和点对即可在 n≤2000n\le2000 时通过。

    复杂度为 O(n2)O(n^2),空间复杂度为 O(n)O(n)。

    算法三:线性 DP 与线段树

    计算 ff 时,候选前驱按下标入栈。坐标 xix_i 单调增加,若栈顶的 ff 已小于 xix_i,它以后永远不会再可行,可以永久弹出;未过期的最大下标就是所需前驱。gg 可对称计算,两趟均为 O(n)O(n)。

    最后从左到右枚举右邻居 jj,在线段树中加入所有满足 fi≥xif_i\ge x_i 的左候选 i<ji<j,叶子保存 fif_i,区间保存最大值。若 gj≤xjg_j\le x_j,在线段树中寻找最右的、值至少为 gjg_j 的下标 ii。它给出当前最短间隙。每次查询为 O(log⁡n)O(\log n)。

    正确性证明

    由 ff 的定义与转移归纳可知,fif_i 精确描述所有从左侧到达 ii 的稳定链可容纳的最右后继;gig_i 对右侧稳定链同理。对任意 i<ji<j,存在新增坐标 yy 连接两条链,当且仅当区间

    [xi,min⁡(xj,fi)]∩[max⁡(xi,gj),xj][x_i,\min(x_j,f_i)]\cap[\max(x_i,g_j),x_j]

    非空,这恰等价于上述三个可行条件。此时新增柱子的左右邻居为 i,ji,j,所需两倍耐久度为 xj−xix_j-x_i。算法枚举每个 jj 并选择最大的可行 ii,所以既不会遗漏可行方案,也为该 jj 取得最小间隙;对所有 jj 取最小即为全局最优。

    复杂度为 O(nlog⁡n)O(n\log n),空间复杂度为 O(n)O(n)。

    实现注意事项

    2di2d_i 与无穷哨兵使用 64 位整数。最优答案的两倍始终是整数,最后除以二输出即可;评测器仍按原题要求使用 10−410^{-4} 的绝对或相对误差。

    复杂度

    三档算法的时间复杂度依次为 O(2nn2)O(2^n n^2)、O(n2)O(n^2) 与 O(nlog⁡n)O(n\log n),空间复杂度依次为 O(n)O(n)、O(n)O(n) 与 O(n)O(n)。

    • 1

    信息

    ID
    1466
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    0
    上传者