四邊形不等式:php
稱代價函數 w 知足凸四邊形不等式,當:\(w(a,c)+w(b,d)\le w(b,c)+w(a,d),\ a < b < c < d\)
以下所示,區間一、2對應的 w 之和 ≤ 三、4之和html
\[ \underbrace {\overbrace {a \to \underbrace{b \to c}_3}^1 \to d }_4 \llap{\overbrace {\phantom{b\to c\to d}}^2} \]web
稱矩陣 \(A\) 凸徹底單調,當:
\(A(a,c)\ge A(b,c)\Rightarrow A(a,d)\ge A(b,d),\ a < b < c < d\)
以下所示,若是知足1區間對應的 w 比2大,那麼能夠推出3比4大。算法
\[ \overbrace {\overbrace {a \to b \to c}^1 \to d }^3 \llap{\underbrace {\underbrace{\phantom{b\to c}}_2\phantom{\to d}}_4} \]數據結構
由四邊形不等式能夠推出徹底單調性,反之不真。app
轉移方程:\(f(j)=\min_{i < j}\{f(i)+w(i,j)\}\)ide
令 \(A(i,j)=f(i)+w(i,j)\)表示狀態 j 從上一列的第 i 行轉移過來的結果。函數
w知足凸四邊形不等式\(\Rightarrow\)w 是凸徹底單調的\(\Rightarrow A\)也是凸徹底單調的\(\Rightarrow\)決策單調。post
令 d(j) 表示最小的知足第 j 行比前面行優的列編號。優化
每一個決策(行)的做用範圍是相互鏈接且遞增的列區間,d(j)就是j做用區間的起點,好比:
111224444,d(1)=1,d(2)=4,d(4)=6
因爲決策單調,咱們用棧維護\(< d(j),j>\)。每次要作的就是:
這樣就從\(O(n^2)\)優化到了\(O(n\log_2n)\)。
轉移方程:\(f(i,j)=\min \{f(i-1,k-1)+w(k,j)\}\)
也是利用決策單調性。
令 d(i, j) 表示 f(i, j) 的最優決策。
\(d(i,j')\le d(i,j) ,j' < j\)
因而能夠在d(i, j) 前面的區間遍歷尋找d(i', j')。
咱們分治的過程 \(solve(opt_L,opt_R,l,r)\) 遍歷\(opt_L\)到\(opt_R\) 計算出中點\(m=(l+r)/2\) 的 d(i, m)。
那麼全部\(l\le x < m\) 的 d(i, x) 必定是在\([opt_L, d(i,m)]\)區間內,全部\(m < x\le r\)的d(i, x) 必定是在\([d(i,m),opt_R]\)區間內。
因此遞歸:
solve(optL,d[i][m],l,m-1); solve(d[i][m],optR,m+1,r);
相關文章:post1
轉移方程:\(\displaystyle f(i)=\min_{j=b[i]}^{i-1}\{g(j)\} + w(i)\),\(b[i]\)隨 i 遞增。
若後面的一個決策更優,那麼前面的決策就能夠刪掉。所以單調隊列維護決策表:
轉移方程: \(f(i)=\min\{a_{i}\cdot x_{j} + b_{i} \cdot y_{j}\}\)
這是一種數形結合的思想。將每一個決策做爲一個點\((x_j,y_j)\),畫在平面直角座標系中,因而咱們要找的是讓\(z=a_{i}\cdot x+ b_{i} \cdot y\) 最小的點。變形獲得\(y=-\frac {a_i}{b_i} \cdot x+\frac z {b_i}\)。也就是找一個點,斜率爲\(-\frac {a_i} {b_i}\)的直線通過該點時,縱截距最小。
能夠發現全部最優決策點在一個凸殼上。
相關文章:
bzoj1492 [NOI2007]貨幣兌換Cash
轉移方程:\(f(i)=\min \{f(j)+b_j*a_i\}\)
其實至關於上式\(a_i=1,x_j=f(j),y_j=b_j,b_i=a_i\),所以也能夠用斜率優化。
將每一個決策\(A(i,j)=\color{blue}{b_j}*a_i+\color{green}{f(j)}\)
做爲一條直線\(y=\color{blue} {m_j}*x+\color{green}{c_j}\),當前狀態選擇的決策就是將\(x=a_i\)帶入全部直線,獲得最小值的那條直線。
咱們用棧維護有效(最小值可能出如今它上面)的直線。
若是\(b_j\)遞減,那麼至關於不斷加入一條斜率更小的直線,它和最後一條直線\(l_1\)的交點若是比\(l_1\)與\(l_2\)的橫座標要更小,則\(l_1\)無效了,從棧中彈出,反覆執行直到橫座標不更小或者只剩棧底,此時入棧。這個過程相似維護凸包。
若是\(a_i\)遞增,那麼每次最小值必定在最後一條直線上。因而複雜度是\(O(n)\)。
相關文章:Convex hull trick
轉移方程:\(f(i,j)=\min \{f(i-1,k)+b_k*a_j\}\)
i 固定時,每一個決策\(A(j,k)=\color{blue}{b_k}*a_j+\color{green}{f(i-1,k)}\),做爲一條直線\(y=\color{blue} {m_k}*x+\color{green}{c_k}\),那麼接下來同上。
故總得複雜度是\(O(kn)\)。
相關文章: post2
轉移方程 \(f(i,j)=\min\{f(i,k-1)+f(k,j)\}+w(i,j)\)
因而轉移方程改寫爲:
\(f(i,j)=\min\{ f(i,k-1)+f(k,j)\}+w(i,j), s(i,j-1)\le k\le s(i+1,j)\)
因爲這個狀態轉移方程枚舉的是區間長度L,假設求f(i,i+L),而每次循環長度之和爲
\[ \begin{aligned} &\sum_{i=1}^{n-L}{s(i+1,i+L)-s(i,i+L-1)}\\ &=s(2,L+1)-s(1,L)+s(3,L+2)-s(2,L+1)+s(4,L+3)-s(3,L+2)..\\ &=s(n-L+1,n)-s(1,L)\le n-1 \end{aligned} \]
枚舉L是的\(O(n)\),因而總的複雜度是\(O(n^2)\)。
Donald E. Knuth 從最優二叉搜索樹的數據結構中提出的。
參考文章: