HNOI2008 玩具装箱Toy(详解)
本文移植自个人的原博客(原文)
题目链接
题目描述
题解
暴力
设$dp[i]$为处理前$i$个玩具的最小花费,$a[i]$为前$i$个玩具长度的前缀和。
易得转移方程为$dp[i]=min \lbrace dp[j]+(i−j−1+a[i]−a[j]−l)^2 \rbrace (0 \leq i < j \leq n)$
此方法时间复杂度为$O(n^2)$,只能水到20分。
|
单调性
观察该题数据范围和状态只有一维的转移方程,我们可以尝试通过斜率优化将时间复杂度降到$O(n)$。
斜率优化中涉及单调队列的使用,自然要求方程满足决策单调性,一般可以通过决策表的方法进行验证,对于此题来说,数据容易生成,可以尝试一下。
|
易观察到$best[i]$单调不降,满足决策单调性。
证明见下:
对于$dp[i]$,当其由$dp[k]$转移而来优于$dp[j]$时,有
$$dp[k]+(i−k−1+a[i]−a[k]−l)^2 < dp[j]+(i−j−1+a[i]−a[j]−l)^2$$
$$dp[k]−dp[j] < (i−j−1+a[i]−a[j]−l)^2−(i−k−1+a[i]−a[k]−l)^2$$
对于该方程,可设
$$b[i]=a[i]+i$$
$$l=l+1$$
则有
$$dp[k]−dp[j]<(b[i]−b[j]−l)^2−(b[i]−b[k]−l)^2$$
化简得
$$((dp[k]+b[k]^2)−(dp[j]+b[j]^2))/(b[k]−b[j])<2b[i]−2l$$
此时的形式为点斜式方程:
$$(yk−yj)/(xk−xj) < ansi$$
已知$b[i]$为前缀和的形式,所以$b[i]$单调递增,可知斜率为单调递增。则适用决策单调性。
设
$$g[k,j]=(yk−yj)/(xk−xj)$$
则当且仅当$g[A1,A2] < b[i]−2l$时,由$A1$转移而来优于$A2$。
当$g[c,b] < g[b,a]$时,易证得$b$必不为最优决策。
当$g[c,b] < ansi$,此时$c$决策优于$b$,则$b$一定不为最优决策。
当$g[c,b]>=ansi$,此时$b$决策优于$c$,但又有$g[b,a]>g[c,b]>=ansi$,此时$b$决策不优于$a$决策。
综上所述,则可将所有满足$g[c,b] < g[b,a]$的决策$b$排除掉。此时函数满足上凸的性质,即有斜率递减。
具体方法
以下我们便可以进行斜率优化(严格建立在决策单调性的基础上):
1: 用单调队列维护点集信息。
2: 求解$dp[i]$,可以从队首开始扫描,当$g(head+1,head) < ansi$时,可知$head+1$优于$head$,故继续扫描,直到不满足条件,此时$bext[i]=head$,即使$dp[i]$最优的决策为队首。
3: 当加入点$i$,我们要维护队列的上凸性质,即从队尾开始扫描,判断$g(i,tail)$是否小于$g(tail,tail-1)$,如果满足,则可删除$tail$,并继续扫描,直到不满足该条件,则$i$在此处入队,队列仍满足上凸性质。
AC代码如下:
|