DP的优化总结

1、预备知识

  1. \(tD/eD\) 问题:状态 t 维,决策 e 维。时间复杂度\(O(n^{e+t})\)
  2. 四边形不等式: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

  1. 凸彻底单调性:

称矩阵 \(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

  1. 区间包含关系单调:w 知足\(w(b,c)\le w(a,d),a\le b\le c\le d\)
  2. 决策单调性:\(r_j\)是使得矩阵A 第 j 列最小的行号。若\(A\)知足凸彻底单调性能够推出\(r_1\le r_2 \le \cdots \le r_m\),即最小值行号递增。

2、优化方法

1. 利用决策单调性

转移方程:\(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>\)。每次要作的就是:

  • 二分找到d(j)在哪一个列区间,弹出后面的区间。
  • 在这个列区间里二分计算出d(j)
  • 入栈

这样就从\(O(n^2)\)优化到了\(O(n\log_2n)\)

2. 分治优化

转移方程:\(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

3. 单调队列

转移方程:\(\displaystyle f(i)=\min_{j=b[i]}^{i-1}\{g(j)\} + w(i)\)\(b[i]\)随 i 递增。
若后面的一个决策更优,那么前面的决策就能够删掉。所以单调队列维护决策表:

  • 队首出队,直到队首符合范围
  • 此时队首就是最优决策
  • 计算出的 g(x)若是比队尾优,不断删除队尾,直到g(x)没有更优,则插入队尾。
  • \(O(n)\)

4. 斜率优化

转移方程: \(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}\)的直线通过该点时,纵截距最小。

能够发现全部最优决策点在一个凸壳上。

  • 若是斜率和 x 都单调,只要用单调队列维护,队尾的删除是由于要维护凸性,队首的删除是由于决策点在凸壳上是单调移动的,当前队首不是最优解,以后也不会是最优解。\(O(n)\)
  • 不然,二分能够找到最优决策点。将凸壳上的点连边,斜率是单调递增的,决策 i 插入时,先根据 x 二分找到插入点,而后两边进行 Graham 维护凸性,就是删点。x 不单调时须要用平衡树动态维护凸包。\(O(n\log_2n)\)
  • 另外能够用 cdq分治 代替平衡树来作。
  • 斜率优化的题通常也能够用分治优化作。

相关文章:
bzoj1492 [NOI2007]货币兑换Cash

5. 凸包优化(Convex Hull Trick)

转移方程:\(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

6. 凸包优化2

转移方程:\(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

7. Knuth优化

转移方程 \(f(i,j)=\min\{f(i,k-1)+f(k,j)\}+w(i,j)\)

  1. 若是 w 知足四边形不等式和 区间包含单调性,那么 f 也知足四边形不等式。
  2. 定义 f 取得最优值的决策:\(s(i, j)\),若是 f 知足四边形不等式,则 s 单调:\(s(i,j-1)\le s(i,j) \le s(i+1,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 从最优二叉搜索树的数据结构中提出的。

相关文章:1 2

3、题目

凸包优化(CHT)

  1. BZOJ 1701-Cow School Solution-Video
  2. SPOJ-APIO2010 Commando
  3. SPOJ-TRAKA
  4. SPOJ-BAABO
  5. SPOJ-ACQUIRE
  6. SPOJ-NKLEAVES
  7. cf91e-SkyScrapers (+Data Structures)
  8. cf311b Cats Transport
  9. cf660f Bear and Bowling 4
  10. cf319c Kalila and Dimna in the Logging Industry
  11. cf631e Product Sum
  12. cf455e Function
  13. cf536c Tavas and Pashmaks
  14. cf377e Cookie Clicker
  15. cf91e Igloo Skyscraper
  16. Jump mission | CodeChef
  17. Contest Page | CodeChef

Knuth 优化

  1. Spoj-BRKSTRNG
  2. UVa10003-Cutting Sticks
  3. UVa10304
  4. Order-Preserving Codes - gym100212C
  5. UVa12057
  6. UVa-12836

分治优化

  1. cf321e Ciel and Gondolas
  2. hr-Guardians of the Lunatics
  3. Chef and Bitwise OR Operation | CodeChef
  4. SPOJ-NKLEAVES
  5. hr-mining
  6. Bicolored Horses
  7. UVa12524
  8. cf673e Levels and Regions
  9. ARC 067D

斜率优化

  1. BZOJ 1597 [Usaco2008 Mar]土地购买
  2. BZOJ 3675 [APIO 2014]序列分割
  3. BZOJ 1010 [HNOI2008]玩具装箱toy
  4. BZOJ 3437 小P的牧场
  5. BZOJ 3156 防护准备
  6. BZOJ 1096 [ZJOI2007]仓库建设
  7. BZOJ 1911 APIO 2010 Commando
  8. BZOJ 4518 [SDOI2016] 征途
  9. HDU 3507
  10. HDU 3401
  11. HDU 2191
  12. HDU 5956 The Elder

平衡树维护动态凸包

  1. cf70d
  2. BZOJ 2300(HAOI2011)防线修建
  3. BZOJ 1492 货币兑换Cash
  4. HDU 5127 Dogs’ Candies

参考文章:

  1. Dynamic programming with convexity, concavity and sparsity
  2. 《算法艺术与信息学竞赛》p149。
  3. 1D1D动态规划优化初步
  4. 动态规划算法的优化技巧-毛子青
  5. dp优化-我的对dp优化的理解
  6. Dynamic Programming Optimizations
  7. 斜率优化 二
相关文章
相关标签/搜索