很容易地,我们首先得到:
s[x]=min{s[k]+(p[x]−p[k]+x−k−L−1)2}
其中, p[n]=∑ni=1C[i]
这样直接计算是会TLE的: O(n2)
下面我们考虑优化:
我们记 f[x]=p[x]+x,c=L+1 ,那么方程简化为:
s[x]=min{s[k]+(f[x]−f[k]−c)2}
先看下 决策单调性
设 k>j 且有
s[k]+(f[x]−f(k)−c)2<s[j]+(f[x]−f[j]−c)2(1)
对于以后的决策,设 y>x 并记 f[y]=f[x]+Δ 显然 Δ>0
若我们的方程有 决策单调性那么我们就有:
s[k]+(f[y]−f[k]−c)2<s[j]+(f[y]−f[j]−c)2
也即
s[k]+(f[x]+Δ−f[k]−c)2<s[j]+(f[x]+Δ−f[j]+c)2
s[k]+(f[x]−f[k]−c)2+2(f[x]−f[k]−c)Δ < <script id="MathJax-Element-174" type="math/tex"><</script> s[j]+(f[x]−f[j]−c)2+2(f[x]−f[j]−c)Δ
我们考虑到两个不等式: 2(f[x]−f[k]−c)Δ<2(f[x]−f[j]−c)Δ 也即 f[k]>f[j]
s[k]+(f[x]−f[x]−c)2<s[j]+(f[x]−f[j]−c)2
两式相加即得我们迫切想看到的 决策单调性
即决策点只向右移动.
我们只有决策单调性是不够的,我们还可以从 (1) 中获取更多信息
我们将 (1) 打开,并将所有有关 j,k 的项移到一边就有
s[k]−2cf[k]+f[k]2−(s[j]−2cf[j]+f[j]2)f[k]−f[j]<2f[x]
嘿!这是什么,斜率?对的.
我们可以以 (f[x],s[x]−2cf[x]+f[x]2) 为点x的坐标画出散点图,再从中找出它的右下凸包,我们仅考虑也仅维护这个凸包,当我们要算 s[y] 时,我们就找凸包上的一个点t,使得它与前面一个点连线的斜率小于 2f[y] 与后面一个点的斜率大于 2f[y] (也就是切线)那么这个点就是最优决策点.我们可以二分做到(凸包上斜率递增).
算完 s[y] 后,我们要将它插入凸包中(它一定在凸包中)这又可以在 O(logn) 的时间内完成.
这样,我们对每个点用 O(logn) 时间搜索最优决策点,用 O(logn) 时间插入新点
总用时 O(nlogn) 对 n<50001 绰绰有余.