干草堆

先倒序处理(为什么下文会说),然后就变成了划分尽量多的段,使得每段的和单调不减

很容易设置出一个状态f[i][j]表示前i堆草,最后一段是[j,i]的最大高度,方程也很容易推导,但是时空复杂度显然炸掉

那么此时我们就应该思考,要么就是利用数组值来搞一些事情(一般是交换两种维度的信息,另一种是可行性转最优性,这里显然都不行),要么就是发现某些引理(一般用贪心)

我们这里就可以想,对一个前i堆草来说,假设能堆到最高高度的方案有若干种,那么我们想要哪一种呢?显然是想要最后一段最小的一种,根据决策包容性易证

于是可以设f[i]表示前i堆草能够堆到的最大高度,g[i]表示所有最大高度的方案中最后一段最小的一种方案的最后一段的长度,s[i]表示前缀和,于是就有

f[i]=maxj<i,s[i]s[j]g[j](f[j])+1

这个时候我们倒序处理的原因就来了。对上面这个式子,看起来有两个条件要满足(在满足max(f[j])最大的情况下让j最大,这样可以让g[i]最小)导致需要使用数据结构优化DP,其实当j最大的时候f[j]也一定是最大的,因为f是单调不减的(我们倒序处理了,现在是让每段的和单调不减,如果f[i]<f[j]i>j,那么对于j的方案,我们直接把[j+1,i]这些干草全部放在j的方案的最后一段就好了,这样就有f[i]=f[j]了)

然后这个时候我们就可以用单调队列解决问题了,想一下单调队列怎么处理:此时单调队列里面存的是所有可能的决策点,但是我们没有必要建立二叉堆和单调队列的映射,因为根据上面的引理,我们只要一直弹出队首直到不满足s[i]s[j]g[j],最后一个弹出的就是最佳决策

update 2024.4.14

重做这道题目,隐约记得是需要倒序处理的,所以直接就往倒序处理想了

然后想了许久,得出来了上面的DP方程,但实际上仅仅凭这些是无法说明这个方法的正确性的

因为可能对当前的i,某个j满足s[i]s[j]<g[j]但是对j来说存在另一种不是最高高度的方案,最底层却更小,然后可以把[j+1,i]这些干草放在这个方案的最底端而且新的这个方案就是对于i来说的最优的方案

所以我们需要证明,对于所有最优的方案,我们找到底端最小的一种方案,那么对于其他所有的方案,底端都不会比我们找出来的这个最优方案更小

当然考试的时候可以猜这个结论,我重做的时候就是一直卡在这个结论的证明上面了

证明实际并不好证明:

设我们找出来的最优方案为P1,假设存在另一种方案P2P2的高度比P1小但是最底端却比P1小,假设P2的高度为h,我们依次从最底端往上进行比较,设第iP1在序列(注意在证明中我们还没有倒序考虑序列,这个序列就是题目给出来的序列)中对应的一段的编号最大干草编号为ai,同理设出P2bi。那么P1的分段就是[a1=1,a2],[a2+1,a3],...P2的分段就是[b1=1,b2],[b2+1,b3],...,[bh1+1,bh=n]

由题,a2>b2(因为P2的底端更小,也就是这一段的和更小),ah<bh=n,所以中间一定存在一个位置k,满足ak1bk1akbk,我们找到最小的这样的k,那么就说明P1的第k层的干草全部都被包含在P2的第k层的干草中,那么我们构造一个新的方案,最底层到第k1层取P2的分法,第k+1层到第HP1的高度)层取P1的分法,然后没有被取到的剩下的干草就放在第k层,不难发现这个新的方法是合法的,而且他的高度与P1一样但是最底层却比P1的最底层更小,与我们最开始的假设矛盾,证毕

有了这个证明,我们才可以说明我们的DP是正确的

update 2024.7.5

其实我们最开始设出f[i][j]表示前i堆草,最后一段是[j,i]的最大高度发现推不走之后,也有可能使我们的方向搞错了,就像“围栏障碍训练场”这道题目一样,所以我们考虑倒序,也许可以发现上面的贪心

可以想一下数据结构如何优化:对f的快速查询就不说了,对g[i],我们有g[i]=s[i]max(s[j]),要求f[j]==f[i]1,于是我们令d[i]表示f值为is值最大的下标,这样就可以O(1)更新了

但是这里证明f单调的思想与“裁剪序列”这道题目非常像,也可以记住

posted @   最爱丁珰  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示