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

本文介绍了一种针对特定类型的动态规划问题的优化方法——DP凸壳优化。通过维护一个差分数组并利用优先队列,可以将复杂度从不可接受的程度优化至O(n^2)。文章还提供了一个具体示例问题“TouchTheSky”的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

对于这样的dp问题:

d p i , j = min ⁡ ( d p i − 1 , j , d p i − 1 , j − 1 + w i ) dp_{i,j}=\min (dp_{i-1,j},dp_{i-1,j-1}+w_i) dpi,j=min(dpi1,j,dpi1,j1+wi),(for example :Touch The Sky)

求任意的 d p i , j dp_{i,j} dpi,j

可以发现 d p i dp_{i} dpi形成了一个凸壳( d p i , j − d p i , j − 1 ≥ d p i , j − 1 − d p i , j − 2 dp_{i,j}-dp_{i,j-1}\geq dp_{i,j-1}-dp_{i,j-2} dpi,jdpi,j1dpi,j1dpi,j2)。

上述dp有两种转移:

  • d p i , j = d p i − 1 , j dp_{i,j}=dp_{i-1,j} dpi,j=dpi1,j,直接复制上一个,没啥好说的。
  • d p i , j = d p i − 1 , j − 1 + w i dp_{i,j}=dp_{i-1,j-1}+w_i dpi,j=dpi1,j1+wi,其实可以这样理解:将 d p i , j dp_{i,j} dpi,j d p i , j − 1 dp_{i,j-1} dpi,j1的差值与 w i w_i wi取一个min。

所以我们可以

若我们维护差分数组 : c j c_j cj= d p i , j − d p i , j − 1 dp_{i,j}-dp_{i,j-1} dpi,jdpi,j1

则在 c j ≥ w i c_j\geq w_i cjwi的部分,所有的 d p i dp_{i} dpi都为 d p i − 1 dp_{i-1} dpi1向上移动 w i w_i wi位,并向右移动一位。

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

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

这里需要有一个限制 d p i − 1 , j − 1 ≤ L i ⇔ d p i − 1 , j − 1 + W i ≤ L i + W i = L ′ i dp_{i-1,j-1}\leq L_i\Leftrightarrow dp_{i-1,j-1}+W_i\leq L_i+W_i=L\prime_i dpi1,j1Lidpi1,j1+WiLi+Wi=Li

这其实非常好办。

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

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

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

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

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

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

所以priority_queue就ok了。

代码也就十多行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值