斜率优化 dp

洛谷P3195 [HNOI2008] 玩具装箱

考虑设计 \(\text{dp}\),令 \(S_i=\sum_{k=1}^iC_k\)\(f_i\) 表示前 \(i\) 个玩具的最小容器费用和,则

\[f_i=\min_{j=0}^{i-1}\underbrace{f_j}_{\substack{前\ j\ 个\\[2pt]的费用}}+\bigl(\underbrace{i-(j+1)+S_i-S_j}_{第\ j+1\ 到第\ i\ 个的容器长度}-L\bigr)^2 \]

\(g_i=i+S_i\),则

\[\begin{align*} f_i&=\min_{j=0}^{i-1}f_j+\bigl(i-(j+1)+S_i-S_j-L\bigr)^2 \\ &=\min_{j=0}^{i-1}f_j+(g_i-g_j-L-1)^2 \\ &=\min_{j=0}^{i-1}f_j+\bigl((g_i-L-1)-g_j\bigr)^2 \\ &=\min_{j=0}^{i-1}f_j+(g_i-L-1)^2-2g_j(g_i-L-1)+g_j^2 \\ &=(g_i-L-1)^2+\min_{j=0}^{i-1}f_j+g_j^2-2g_j(g_i-L-1) \end{align*} \]

\[y_j=f_j+g_j^2 \]

\[x_j=g_j \]

\[k_i=2(g_i-L-1) \]

\[b_i=f_i-(g_i-l-1)^2 \]

则上式变为

\[b_i=\min_{j=0}^{i-1}y_j-x_jk_i \]

即,要找出一个 \(j\in[0,i-1]\),使得

\[b_i=y_j-x_jk_i \]

\[k_ix_j+b_i=y_j \]

\(b_i\) 最小.

这等价于斜率为 \(k_i\) 的直线在平面上的所有点对 \((x_j,y_j)\) 中选择一个经过使得截距最小,即斜率为 \(k_i\) 的直线从 \(y\) 轴趋于负无穷处向上平移直到交于某一点 \((x_j,y_j)\).

以下是一个例子(与本体实际情况无关):

我们发现,交点只会是所有点 \((x_j,y_j)\) 组成的下凸壳上的点,因为直线一定会先与它外部的点相交. 证明方法是将其与下凸壳上左右相邻两个点分别连线,并得出最终交于该点的斜率范围,然后证明这两个范围交集为空.

其次,设直线 \(y=kx+b\) 交下凸壳于 \(P\),设 \(l_1\)\(P\) 与下凸壳上与左边点相连的线段,\(l_2\)\(P\) 与下凸壳上右边点相连的线段,设 \(l_1\) 的斜率为 \(k_1\)\(l_2\) 的斜率为 \(k_2\),则 \(k_1\leq k<k_2\)(考虑到该直线与下凸壳上某边重合的情况). 于是我们在下凸壳中找到第一个斜率大于 \(k\) 的边,取其左端点即为 \((x_j,y_j)\),可以计算得到 \(b_i\). 因为下凸壳上的线段斜率依次递增,所以可以使用二分查找以 \(O(\log n)\) 的时间复杂度得到答案,其中 \(n\) 为下凸壳大小.

因为 \(C_i>0\),所以 \(S_i\) 是单调递增的,又因为 \(\text{id}\) 函数是单调递增的,所以 \(g_i\) 是单调递增的. 因为斜率 \(k_i=2(g_i-L-1)\),所以 \(k_i\) 也是单调递增的. 因此,对于每一个 \(i\),设转移点为 \(p_i\),则 \(p_i\) 是单调不减的.(类似旋转卡壳的思想). 因此,我们使用单调队列维护下凸壳,每次查询时,不断弹掉队头,直到剩下的下凸壳中,开头的线段的斜率大于 \(k_i\),此时转移点为下凸壳的左端点.

于是可以以 \(O(n)\) 的时间复杂度通过本题.

洛谷P5504 [JSOI2011] 柠檬

\(f_i\) 表示把前 \(i\) 个贝壳全部变为柠檬的最大柠檬数量. 设 \(w_{i,j}\) 表示区间 \([1,i]\) 中大小为 \(j\) 的贝壳的数量,则

\[f_i=\max_{\substack{1\leq j\leq i\\1\leq s\leq 10^4}}\underbrace{f_{j-1}}_{\substack{前\ j-1\ 个\\[2pt]最大数量}}+\underbrace{s(w_{i,s}-w_{j-1,s})^2}_{\substack{将\ [j,i]\ 中大小为\ s\ 的\\[2pt]贝壳变为柠檬的数量}} \]

首先,\(f\) 是单调不减的. 注意到 \(f_i\) 的转移点一定可以来自于与它贝壳大小相同的 \(j\),否则将 \(j\) 增加 \(1\) 后值不会更小.

于是转移式变为

\[\begin{align*} f_i&=\max_{\substack{1\leq j\leq i\\[1pt]s_j=s_i}}f_{j-1}+s(w_{i,s}-w_{j-1,s})^2 \\ &=\max_{\substack{1\leq j\leq i\\[1pt]s_j=s_i}}f_{j-1}+s\cdot w_{i,s}^2-2s\cdot w_{i,s}\cdot w_{j-1,s}+s\cdot w_{j-1,s}^2 \\ &=s\cdot w_{i,s}^2+\max_{\substack{1\leq j\leq i\\[1pt]s_j=s_i}}f_{j-1}+s\cdot w_{j-1,s}^2-2s\cdot w_{i,s}\cdot w_{j-1,s} \end{align*} \]

\[x_j=w_{j-1,s} \]

\[y_j=f_{j-1}+s\cdot w_{j-1,s}^2 \]

\[k_i=2s\cdot w_{i,s} \]

\[b_i=f_i-s\cdot w_{i,s}^2 \]

则上式变为

\[b_i=\max_{\substack{1\leq j\leq i\\[1pt]s_j=s_i}}y_j-k_ix_j \]

即求最大的截距. 于是我们维护 \((x_j,y_j)\) 组成的上凸壳.

\(y=kx+b\) 与凸壳的交点与左边点连线得到 \(l_1\),与右边点连线得到 \(l_2\),设 \(l_1\) 的斜率为 \(k_1\)\(l_2\) 的斜率为 \(k_2\),则 \(k_1\geq k>k_2\). 于是找出第一个斜率小于 \(k\) 的线段,取其左端点,得到对应 \(j\).

于是我们对于每种贝壳大小维护一个上凸壳,可以以 \(O(n\log n)\) 的时间复杂度通过本题.

posted on 2026-08-01 18:34  吴一鸣  阅读(19)  评论(0)    收藏  举报

导航