CF311B Cats Transport

特意单独拿出来单独写。

这道题的 DP 很好想到,我们考虑使用相对运动,就是算每个猫咪需要某管理员在什么时候出发正好接到。将这个东西排序之后,我们发现这个就转化成了在长为 \(m\) 的序列上分 \(p\) 段的一个问题,显然可以 2D/1D DP。

\(P_i\) 为排序后的 \(t_i-t_1\)(将 \(t_1\) 归零),那么我们如果想要 \(O(1)\) 计算一段的贡献就需要前缀和,设 \(pre_i\)\(P_i\) 的前缀和,那么有:

\[\begin{aligned} w(l,r)&=\sum_{i=l}^r P_r-P_i\\ &=(r-l+1)P_r-(\sum_{i=l}^r P_i)\\ &=(r-l+1)P_r-pre_r+pre_{l-1} \end{aligned} \]

实际 DP 的时候是计算的 \(w(j+1,i)\)。设 \(dp_{i,j}\) 为目前 \(i\) 个管理员把前 \(j\) 个猫接走的最小代价,有:

\[dp_{i,j}=\min_{p<j}(dp_{i-1,p}+(j-p)P_j-pre_j+pre_p) \]

这个时候可以拆后面的贡献,发现有 \((-p)P_j+pre_p+dp_{i-1,p}\),那么有 \(k=-j,b=pre_{j}+dp_{i,j}\),然后发现 \(k\) 斜率单调插入,询问 \(x=P_j\) 也单调,那么可以斜率优化。

但是这个是一个分层斜率优化,所以我们也开层数个单调队列来应对,每一次调用上一层的单调队列并更新当前层的单调队列。这个时候就有可能出现转移时 \(p\geq j\) 的情况,但是稍加思索发现这样转移一定不优,所以在单调队列中它一定排在后面。

最后注意整数除法的向上取整的方法需要保证被除数是正数,否则要变号,所以这里推荐直接 double 计算后加 0.9999,不然就自己讨论一下加入的直线的顺序以及比较的传参时的顺序。

时间复杂度 \(O(mp)\),763ms,所以决策单调性的两种方法(分治与特殊分层优化)很难通过。

posted @ 2024-02-29 20:30  xingyu_xuan  阅读(8)  评论(0编辑  收藏  举报