四边形不等式与决策单调性

四边形不等式与决策单调性

四边形不等式

首先,给出四边形不等式的定义:

定义一

设 \(w(x,y)\) 是定义在整数集合上的二元函数,若对于定义域上的任意整数 \(a,b\) ,其中有 \(a<b\) ,都有:

\[w(a,b+1)+w(a+1,b) \ge w(a,b)+w(a+1,b+1) \]

则称函数 \(w\) 满足四边形不等式

定义二

设 \(w(x,y)\) 是定义在整数集合上的二元函数,若对于定义域上的任意整数 \(a,b,c,d\) ,其中有 \(a\le b\le c\le d\) ,都有:

\[w(a,d)+w(b,c) \ge w(a,c)+w(b,d) \]

则称函数 \(w\) 满足四边形不等式

方便记忆:交叉小于包含

简单证明一下定义二:

四边形不等式与决策单调性

决策单调性

定义

形如 \(f[i]=min \{ f[j]+val(j,i) \} (0\le j\le i)\) 的状态转移方程,如果 \(p[i]\) 为状态 \(f[i]\) 的决策,并且数组 \(p\) 在 \([1,N]\) 上单调不减,简称 \(f\) 具有决策单调性

还有一个性质,形如上述的状态转移方程中,若 \(val(j,i)\) 符合四边形不等式,那么 \(f\) 具有决策单调性。

四边形不等式与决策单调性

看到最后的式子,即决策点 \(p[i]\) 一定不劣于决策点 \(j\) ,并且 \(j<p[i]\) ,即得证。

用法

显然,最简单的优化为将状态转移方程写作:

\[f[i]=min \{ f[j]+val(i,j) \} ( p[i-1]\le j\le i ) \]

缩小了决策范围,但这样做却不一定能更优,例如 \(p=\{ 1,1,1,1,1,1,1,1 \}\)

所以我们肯定存在其他方法。

当循环到某一个 \(i\) 时, 有可能 \(p=\{ j_1j_1j_2j_2j_2j_3j_3j_3j_4j_4j_5j_5j_5 \}\)

其中 \(j_1<j_2<j_3<j_4<j_5<i\)

当求解出 \(f[i]\) 后,我们即可以更新 \(p\) ,也就是找到一个点 \(k\) ,比较当它的决策点为 \(i\) 时与决策点为 \(p[k]\) 时的大小,若前者更优,那我们就把它和它之后所有点的决策换为 \(i\) ,即 \(p=\{ j_1j_1j_2j_2j_2j_3iiiiiii \}\)

这么做相当于我们实现了动态更新 \(p\) 数组。

但这个过程该如何实现呢?暴力的效率是相当低的,不能达到我们的优化目的。

考虑使用一个队列代替 \(p\) 数组,队列中保存若干个三元组 \((j,l,r)\) ,其中 \(j\) 为决策, \(l,r\) 为区间。

例如:

\(p=\{ j_1j_1j_2j_2j_2j_3j_3j_3j_4j_4j_5j_5j_5 \}\) 可以表示为 \((j_1,1,2)(j_2,3,5)(j_3,6,8)(j_4,9,10)(j_5,11,13)\)

当更新 \(i\) 的时候,发现 \((j_4,9,10)(j_5,11,13)\) 的左端点的决策都比 \(i\) 更劣,从队列中将其删去。但是 \((j_3,6,8)\) 左端点比 \(i\) 更优,右端点比 \(i\) 劣,那我们就二分找到一个中间点更新即可。

如何通过这个队列维护求解 \(f\) 数组,实际上它是个动态更新的过程,但显然前面已经使用过的都是我们不需要的,每次用完过后将其出队,这样每次更新 \(f\) 的值我们就只需要取出队头即可。

总结

上述过程有些凌乱,此部分梳理一下其具体过程

  • 对于每个 $i\in [1,N] $ ,我们执行一下操作:

    • 检查队头 \(( j_0,l_0,r_0 )\) ,若 \(r_0<i\) ,删除队头,否则:\(l_0=i\) 。
    • 取出队头 \(j\) ,作为最优决策,算出 \(f[i]\) 。
    • 插入决策 \(i\)
      • 取出队尾 \((j_t,l_t,r_t)\) 。
      • 如果对于 \(f[l_t]\) ,\(j_t\) 劣于 \(i\) ,即 \(f[i]+val(i,l_t) \le f[j_t]+val(j_t,l_t)\) ,删除队尾,记 \(pos=l_t\) 。
      • 如果对于 \(f[r_t]\) ,\(j_t\) 优于 \(i\) ,则将 \((i,pos,N)\) 插入队尾,结束该过程。
      • 如果上述两点都不满足,则在 \([l_t,r_t]\) 中进行二分,找到最小 \(pos\) 满足 \(f[i]+val(i,pos) \le f[j_t]+val(j_t,pos)\) ,则将 \((j_t,l_t,pos-1),(i,pos,N)\) 插入队尾。
上一篇:全球邀请开发者 滴滴启动KDD Cup 2020强化学习挑战赛


下一篇:Luogu5334 [JSOI2019]节日庆典