首先
对于形如(f[i]=min(f[j]+cost[j]),0<j<i)的(dp),
我们可以利用维护一个变量取最小值去维护这个(dp)方程。
再者;
对于形如(f[i]=min(f[j]+cost[j]),i-k<j<i)的(dp),
我们可以发现,只用维护一段序列中的最小值即可。。
这时候,由于决策具有单调性,我们可以利用单调性来维护,
只用,利用单调队列来维护区间最值即可。
可是,对于形如:
(f[i]=min(f[j]+cost[i][j]),0<j<i)
我们应该如何去维护呢???
如果延用上面的单调性去维护的话,我们会面临一个尴尬的境界,
我们发现,(cost[][])函数与(i,j)都有关。
无法利用单调性来维护。
怎么办呢。。。。
现在,让我们来请出最后最强大的方法。
斜率优化
斜率优化是对于形如(f[i]=min(f[j]+cost[i][j]),0<j<i)的方程的优化。
可以把复杂度由本来的(O(n^2))优化到(O(n))或(O(nlogn))的复杂度。
决策单调性
首先,对于斜率优化的方程,先进行证明决策单调性。
对于形如,(f[i]=min(a[i]*b[j]+c[j]+d[i]))的方程,决策点一定具有单调性。
首先,(a[x],b[x],c[x],d[x])是关于(x)的函数,且(b[x])单调递增。
首先假设(k<j)且(f[j]<=f[k]);
即决策(j)比(k)更优;
即
(a[i]*b[j]+c[j]+d[i]<=a[i]*b[k]+c[k]+d[i]cdots (1))
下面有一个新的待决策点(a[i+1])
设(a[i+1]=a[i]-v),即(a[i])单调递减。
我们要证下列式子
(a[i+1]*b[j]+c[j]+d[i+1]<=a[i+1]*b[k]+c[k]+d[i+1])
((a[i]-v)*b[j]+c[j]+d[i+1]<=(a[i]-v)*b[k]+c[k]+d[i+1])
(a[i]*b[j]-v*b[j]+c[j]<=a[i]*b[k]+c[k]-v*b[k])
(a[i]*b[j]+c[j]-v*b[j]<=a[i]*b[k]+c[k]-v*b[k])
由于(b[])单调递增->(v>0);
我们又有((1));
所以,可证在(k<j)且决策点(j)比决策点(k)更优的情况下。
决策点(k)一定不会在有用,因此,
决策具有单调性
我们将前面的式子展开得到
(a[i]*(b[j]-b[k])<=c[k]-c[j];)
(-a[i]<=frac {c[k]-c[j]}{b[k]-b[j]})
(S(k,j)=frac {c[k]-c[j]}{b[k]-b[j]})
- 我们可以发现,关于对于队首,若(-a[i]<=S(Q[L],Q[L+1])),则说明决策(Q[L])比决策(Q[L+1])无用,可以(pop)掉。
- 对于队尾,若有(S(Q[R-1],Q[R])<S(Q[R],i)),则说明若决策点(Q[R-1])被(pop)掉了后,决策点(Q[R])一定会被(pop)掉,则可以直接把(Q[R])给(pop)掉。
关于何时(pop)队首,我们要考虑一下。
- 若斜率(a[i])单调,直接按斜率(pop)即可。。
- 否则,我们无法(pop)队首,则需要在队列里二分寻找最优值。
证毕。。。