[unknown OJ] 施工

一、题目

点此看题

二、解法

方法1 fnm dp

看数据范围,如果从 d p dp dp的角度来思考,那么设 d p [ i ] dp[i] dp[i] . . . . . . ...... ......(只有这种定义可行一点了)

增加高度很重要?状态定义又不能要。那么我们定义 d p [ i ] dp[i] dp[i] i i i作为不动建筑的最小花费(分为两种),问题是这种定义是否能转移?

d p dp dp的本质是所有可能情况的枚举,我们不妨枚举一段都升高了(显然会枚举所有情况),如何升高我们暂时还不知道,需要分析。首先 i i i j j j(这一段的左边那个)一定要比这一整段都高,不然都升高显然是吃力不讨好的操作(注意,这是转移条件哦)。

然后我们知道这一段中最高的建筑升高了,但如果他两边的建筑升得没有这么高,那还不如他不升高呢!所以他两边的建筑也会升高到同一高度,进而得出这一整段都会最终升高到同一高度。设这个高度是 t t t,转移:
d p [ i ] = d p [ j ] + ∑ k = j + 1 i − 1 ( t − a [ k ] ) + c ( a [ i ] + a [ j ] − 2 t ) dp[i]=dp[j]+\sum_{k=j+1}^{i-1}(t-a[k])+c(a[i]+a[j]-2t) dp[i]=dp[j]+k=j+1i1(ta[k])+c(a[i]+a[j]2t)那么 t t t 的最优取值可以通过二次函数来确定,时间复杂度 O ( n 2 ) O(n^2) O(n2)

优化转移的主要方法是观察转移条件,我们可以维护一个单调栈。一个元素插入单调栈时弹出比他小的元素,这些元素是可以转移的(其他元素根据单调栈的性质是不可以转移的)。然后没弹出的那个也是可以转移的,所以有效的转移是 O ( n ) O(n) O(n)的,用单调栈可以达到这一点。

方法2 jzm yyds

这种方法的核心思想是缩小问题规模

如果缩小问题规模?对于一开始的形式,最高的建筑是肯定不会升高的,那么以他为界把原序列花费成两部分。以此类推,一直划分下去(相当于一颗笛卡尔树),看图:

在这里插入图片描述

左边的部分如果原来就没到 max ⁡ \max max(他那一块的最高值),那么就不需要提升了(因为你传下去的时候没有提升,现在肯定不能提升了)。右边的部分如果提高到了 max ⁡ \max max,那么是可以继续提高的(会缩小和高度的差距),右边提升的高度可以通过二次函数来计算(和 d p dp dp的方法一样)

什么都没有
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值