【算法讲解】DP优化——四边形不等式优化(2)

前言

上文讲了四边形不等式在一类 DP 问题中的优化策略
可能大家会觉得,这么复杂的定理,结果只用应用在某类固定 dp 方程上,有点大炮打蚊子的感觉
本文带来了四边形不等式在另外一类非常常见的 dp 方程的应用

分治 DP

d p ( i , j ) = { min ⁡ 0 < k ≤ j { d p ( i − 1 , k ) + c ( k , j ) } , i > 0 0 , i = 0 dp(i,j) = \left\{ \begin{aligned} \min_{0<k\le j} \{dp(i-1,k) + c(k,j)\} &, i > 0 \\ 0 &, i=0 \end{aligned} \right. dp(i,j)= 0<kjmin{dp(i1,k)+c(k,j)}0,i>0,i=0
dp 方程说明:

朴素实现复杂度:此 dp 方程有 n ⋅ m n\cdot m nm 个状态( 1 ≤ i ≤ n , 1 ≤ j ≤ m 1\le i \le n, 1\le j \le m 1in,1jm),每个状态需要有 O ( m ) O(m) O(m) 个决策( k k k 1 1 1遍历到 j j j),对于函数 c c c 我们就当 O ( 1 ) O(1) O(1) 的复杂度,所以整体复杂度是 O ( n ⋅ m 2 ) O(n\cdot m^2) O(nm2)
特征:每一层的 dp 状态由上一层的 dp 状态推演出,而上一层的状态已经在前置逻辑中计算好

我们可以将上述方程进行一些简化,设 C u r r e n t ≔ d p ( i ) \textcolor{Red}Current\coloneqq dp(i) Current:=dp(i) 代表当前层状态,设 B e f o r e ≔ d p ( i − 1 ) \textcolor{Red}Before\coloneqq dp(i-1) Before:=dp(i1) 代表上一层已经计算好的状态,则:
C ( i ) = min ⁡ 0 < j ≤ i { B ( j ) + c ( j , i ) } C(i) = \min_{0<j\le i} \{B(j) + c(j, i)\} C(i)=0<jimin{B(j)+c(j,i)}
接下来我们看看对于这种 dp 方程,四边形不等式可以得出什么推论以帮助我们优化

推论:最佳决策点的单调性

如果函数 c c c 符合四边形不等式,那么 C ( i ) C(i) C(i) 的最佳决策点 o p t ( i ) opt(i) opt(i),必定符合 o p t ( i ) ≤ o p t ( i + 1 ) opt(i) \le opt(i+1) opt(i)opt(i+1)

证明

x = o p t ( i ) , y = o p t ( i + 1 ) x=opt(i), y=opt(i+1) x=opt(i),y=opt(i+1)
用反证法,假设 x > y x > y x>y
由定义可得 x < i , y < i + 1 x<i, y<i+1 x<i,y<i+1
结合假设可得 y < x < i < i + 1 y < x < i < i +1 y<x<i<i+1
x x x C ( i ) C(i) C(i) 的最佳决策点(其他的选择都比它要差),可得 B ( x ) + c ( x , i ) ≤ B ( y ) + c ( y , i ) B(x) + c(x, i) \le B(y) + c(y, i) B(x)+c(x,i)B(y)+c(y,i)
y y y C ( i + 1 ) C(i+1) C(i+1) 的最佳决策点,可得 B ( y ) + c ( y , i + 1 ) ≤ B ( x ) + c ( x , i + 1 ) B(y) + c(y, i + 1) \le B(x) + c(x, i + 1) B(y)+c(y,i+1)B(x)+c(x,i+1)
两式相加去除相同项,可得 c ( x , i ) + c ( y , i + 1 ) ≤ c ( y , i ) + c ( x , i + 1 ) c(x,i)+c(y,i+1) \le c(y,i)+c(x,i+1) c(x,i)+c(y,i+1)c(y,i)+c(x,i+1)
与 c 符合四边形不等式,既 c ( y , i ) + c ( x , i + 1 ) ≤ c ( x , i ) + c ( y , i + 1 ) c(y,i) + c(x,i+1) \le c(x,i) + c(y, i+1) c(y,i)+c(x,i+1)c(x,i)+c(y,i+1) 冲突
所以假设不成立
因此证明 x ≤ y x \le y xy,既 o p t ( i ) ≤ o p t ( i + 1 ) opt(i)\le opt(i+1) opt(i)opt(i+1)

利用定理加速 dp 决策

o p t ( i ) ≤ o p t ( i + 1 ) opt(i)\le opt(i+1) opt(i)opt(i+1) 也意味着 o p t ( i − 1 ) ≤ o p t ( i ) opt(i-1)\le opt(i) opt(i1)opt(i)
如果我们已经知道了其中一个状态 C ( i ) C(i) C(i) 的最佳决策点,那么:

  • 对于所有的 C ( j ) , j < i C(j),j<i C(j),j<i,只需要在 ( 0 , m i n ( o p t ( i ) , j ) ] (0, min(opt(i), j)] (0,min(opt(i),j)] 的范围中进行决策就行了
  • 对于所有的 C ( j ) , j > i C(j),j>i C(j),j>i,只需要在 [ o p t ( i ) , j ] [opt(i),j] [opt(i),j] 的范围中进行决策就行了

所以,我们可以先计算所有状态里最中间的状态 C ( m 2 ) C(\frac{m}{2}) C(2m),记录下最佳决策点 o p t ( m 2 ) opt(\frac{m}{2}) opt(2m)

决策范围是 ( 0 , m 2 ] (0,\frac{m}{2}] (0,2m],所以中共进行了 m 2 + 1 \frac{m}{2}+1 2m+1 次决策,复杂度为 O ( m ) O(m) O(m)

然后计算状态 C ( m 4 ) C(\frac{m}{4}) C(4m) C ( 3 ⋅ m 4 ) C(\frac{3\cdot m}{4}) C(43m)

对于 C ( m 4 ) C(\frac{m}{4}) C(4m),决策范围是 ( 0 , min ⁡ ( m 4 , o p t ( m 2 ) ) ] (0, \min(\frac{m}{4}, opt(\frac{m}{2}))] (0,min(4m,opt(2m))],所以有 min ⁡ ( m 4 , o p t ( m 2 ) ) + 1 \min(\frac{m}{4}, opt(\frac{m}{2}))+1 min(4m,opt(2m))+1次决策
对于 C ( 3 ⋅ m 4 ) C(\frac{3\cdot m}{4}) C(43m),决策范围是 [ o p t ( m 2 ) , 3 ⋅ m 4 ] [opt(\frac{m}{2}), \frac{3\cdot m}{4}] [opt(2m),43m],所以有 3 ⋅ m 4 − o p t ( m 2 ) + 1 \frac{3\cdot m}{4}-opt(\frac{m}{2})+1 43mopt(2m)+1次决策
两者的决策次数为
3 ⋅ m 4 − o p t ( m 2 ) + 1 + m i n ( m 4 , o p t ( m 2 ) ) + 1 = m i n ( 3 ⋅ m 4 − o p t ( m 2 ) + m 4 , 3 ⋅ m 4 − o p t ( m 2 ) + o p t ( m 2 ) ) + 2 = m i n ( m − o p t ( m 2 ) , 3 ⋅ m 4 ) + 2 = O ( m ) \begin{aligned} &\frac{3\cdot m}{4}-opt(\frac{m}{2})+1+min(\frac{m}{4}, opt(\frac{m}{2}))+1 \\ =&min(\frac{3\cdot m}{4}-opt(\frac{m}{2})+\frac{m}{4}, \frac{3\cdot m}{4}-opt(\frac{m}{2})+opt(\frac{m}{2}))+2 \\ =&min(m-opt(\frac{m}{2}), \frac{3\cdot m}{4}) + 2 \\ =&O(m) \end{aligned} ===43mopt(2m)+1+min(4m,opt(2m))+1min(43mopt(2m)+4m,43mopt(2m)+opt(2m))+2min(mopt(2m),43m)+2O(m)

如此往复递归,直到分治收敛。根据二分特性,递归会有 O ( log ⁡ m ) O(\log m) O(logm)层,每一层的复杂度都是 O ( m ) O(m) O(m),所以整体的复杂度为 O ( m ⋅ log ⁡ m ) O(m \cdot \log m) O(mlogm)

可以用另一种更直观的方式来看复杂度
对于任意层每个节点所需要决策的范围(记为 [ d 1 , l , d 1 , r ] [d_{1,l}, d_{1,r}] [d1,l,d1,r]),决策次数的总和为
c n t = d 1 , r − d 1 , l + 1 + d 2 , r − d 2 , l + 1 ⋯ + d m , r − d m , l + 1 cnt=d_{1,r}-d_{1,l}+1 + d_{2,r}-d_{2,l}+1\cdots + d_{m,r}-d_{m,l}+1 cnt=d1,rd1,l+1+d2,rd2,l+1+dm,rdm,l+1
根据决策点单调性的推论,一定是互不相交的
所以可得 d 1 , l ≤ d 1 , r ≤ d 2 , l ≤ d 2 , r ≤ ⋯ ≤ d m , l ≤ d n , r d_{1,l} \le d_{1,r} \le d_{2,l} \le d{2,r} \le \cdots \le d_{m,l} \le d_{n,r} d1,ld1,rd2,ld2,rdm,ldn,r,既 d i , r − d i + 1 , l ≤ 0 d_{i,r}-d_{i+1,l}\le 0 di,rdi+1,l0,用这个不等式多项式中两项进行消消乐,可得
c n t ≤ d m , r − d 1 , r + m = O ( m ) cnt\le d_{m,r} - d_{1,r} + m=O(m) cntdm,rd1,r+m=O(m)
用不严谨的话来说就是:每个决策点平均最多会被访问两次

代码

const int MAXM = 1000001;
int bef[MAXM], cur[MAXM];

int c(int l, int r);

void compute(int l, int r, int optl, int optr) {
  if (l > r) return;
  int mid = (l + r) >> 1;
  cur[mid] = INFINITY;
  int opt = optl;
  for (int i = optl; i <= min(optr, mid); i++) {
    int x = bef[i] + c(i, mid);
    if (x < cur[mid]) {
      cur[mid] = x;
      opt = i;
    }
  }
  compute(l, mid - 1, optl, opt);
  compute(mid + 1, r, opt, optr);
}

int solve(int n, int m) {
  memset(bef, 0, sizeof(bef));
  for (int i = 1; i <= n; i ++) {
    compute(1, m, 1, m);
    memcpy(bef, cur, sizeof(cur));
  }
  return bef[m];
}

练习

Codeforce 1832 F 3200

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值