dp on 凸壳总结&gym 101806 T Touch The Sky 题解

dp on 凸壳总结&gym 101806 T Touch The Sky 题解

我也不知道这个玩意究竟叫什么。。。。

对于这样的dp问题:

\(dp_{i,j}=\min (dp_{i-1,j},dp_{i-1,j-1}+w_i)\),(for example :Touch The Sky)

求任意的\(dp_{i,j}\)

可以发现\(dp_{i}\)形成了一个凸壳(\(dp_{i,j}-dp_{i,j-1}\geq dp_{i,j-1}-dp_{i,j-2}\))。

上述dp有两种转移:

  • \(dp_{i,j}=dp_{i-1,j}\),直接复制上一个,没啥好说的。
  • \(dp_{i,j}=dp_{i-1,j-1}+w_i\),其实可以这样理解:将\(dp_{i,j}\)\(dp_{i,j-1}\)的差值与\(w_i\)取一个min。

所以我们可以

若我们维护差分数组 :\(c_j\)=\(dp_{i,j}-dp_{i,j-1}\)

则在\(c_j\geq w_i\)的部分,所有的\(dp_{i}\)都为\(dp_{i-1}\)向上移动\(w_i\)位,并向右移动一位。

我们只需要在那个维护c数组的平衡树中插入一个\(wi\)即可。同时维护前缀和。

我们回到上面的那一个问题,Touch The Sky。

这里需要有一个限制\(dp_{i-1,j-1}\leq L_i\Leftrightarrow dp_{i-1,j-1}+W_i\leq L_i+W_i=L\prime_i\)

这其实非常好办。

只需要在那个treap里删除最后一个满足上述条件的位置即可。

这样我们就可以将一个看似没有办法优化的二维dp优化到了\(O(n^2)\),是不是非常神奇!

但是有人会说:“treap也太难打了吧,这么长的代码比赛怎么来得及写啊!”。

先别着急,Touch The Sky 这题的确可以不使用treap。

我们先看看最终题目是要求什么?并不是任意的\(dp_{i,j}\)而是凸壳的最上面的那一点的横坐标!再看看\(L\prime_i\)有什么性质,对,递增,这可以保证凸壳的最高点只会升高不会降低!(为啥递增很多题解都解释的非常清楚了,这里就不多说了)

所以我们从前到后考虑,每次加入一个差分值:\(W_i\)。若\(sum> L\prime _i\),就删除最后的那一个(最大的那一个)\(prefix\ sum \leq L\prime _i\)的差分值(这里的prefix sum位再treap里维护的前缀和),可以发现就是最大的那一个(前面已经分析了\(L\prime _i\)递增)。

所以priority_queue就ok了。

代码也就十多行。

posted @ 2020-11-11 17:56  WWW~~~  阅读(104)  评论(0编辑  收藏  举报