如題,動態規划的斜率優化
給出如下一個狀態轉移方程:
f[i]=max{x[j]*x[i]-2*f[j]}
(我們假設x[i]單調增——她也許就是一個正整數列的前綴和)
我們需要一種基於該轉移的快速求解f[i]的方法
觀察發現:
f[i]的取值與x[j],x[i],f[j]有關;
由於,對於一個f[i],x[i]的取值已然卻定;
於是答案的大小取決於x[j]與f[j],換言之,取決於對j的決策對答案的貢獻;
(這不廢話么)
一個挺好的想法是枚舉j,找出max;
(慢得要死了)
一個挺好的想法是將f[i]看為函數值;
一個空空如也的坐標系
那么x[j],x[i],f[j]三項中得有一個為自變量;
。。。。。。。。。。。。
(博主企圖解釋為什么取x[i]為自變量,然后放棄了)
總之取x[i]為自變量,可以把式子化為直線方程;
看出 :
k:x[j];
b:-2*f[j];
於是,f[i]看做x=x[i]時的函數值;
於是我們畫出f[i]=x[j]*x[i]-2*f[j]在不取MAX的可能的情況(因為j的不唯一,而存在多條直線)
豎線表現x[i]的取值;
於是觀察下函數:
f[i]=max{x[j]*x[i]-2*f[j]}
(多了個max)
當我們的j有很多選項時;
意味着有很多直線存在;
但max的存在意味着我們的函數只看處於最上面的一段直線
黃線看做函數的真正圖像;
恩,一個半平面交,但先不考慮這個;
由於,x[]單增;
即k,和自變量單增;
所以直線們本來就是按越來越邪的順序加入隊列的
由於x[i]的遞增,對f[i]貢獻的線也理應越來越邪(即x小時,k小的線還能占點b的優勢,隨x的增加,b的優勢就消失了)
於是維護單調隊列,當隊首這個斜率的直線不如下一條優時,她就失去意義了,該出隊了,因為之后的x[]只會越來越大,她與大斜率之間的差距只會越來越大。
於是取現在的隊首信息構成f[i]的答案
還有一點注意的;
即,隊尾的出隊操作;
我們需要用隊尾的出隊操作維護一個半平面交;
方法是如果隊尾前1個位置的直線與要加入隊列的直線的交點在隊尾直線之上,則隊尾出隊,重復多次直至不符合條件;
為什么維護平面交?
可以看出,當出現上圖、也是上文中提到的情況時;
紫線連函數的一部分都不是,當然貢獻不了答案了
換言之,維護半平面交即是維護函數圖像的過程;
(也可以說函數圖像具有半平面交的性質)
這個性質的作用:
對,這是上文的句子;
但她本身有些欠考量;
這句話成立的前提條件,是維護了半平面交;也就是使上圖中的紫線不在隊列里;
不然紫線會因為自己的弱小,襯托出要選小斜率直線的假象;
友情提示:加黑字體(不含本句)即是具體要做的操作;