ACM算法总结 动态规划(二)(dp优化)

本文深入讲解了DP算法的四种优化技巧:线段树优化、单调队列优化、分治优化和斜率优化,通过实例详细解析了每种优化方法的应用场景和实现过程。



线段树优化dp

当递推的时候,整个区间的变化都是一样的,就可以考虑用线段树加速dp递推。



单调队列优化dp

对于某一个 i 进行 dp 时,其左边的最优决策点假如是 j,如果 j 随着 i 的增长是单调递增的,那么可以用单调队列优化:队首是最优决策点,然后每次把不符合条件的队首弹出,把更劣的队尾弹出,然后把当前决策点加入队尾。这样保证每个点入队一次出队一次,复杂度为 O ( n ) O(n) O(n)

有 n 个烽火台,每个烽火台点亮的代价为 a[i],连续 m 个烽火台至少要有一个点亮,问最小代价。

f i f_i fi 表示点亮第 i 个烽火台的最小代价,显然有 f i = min ⁡ j ≥ i − m f j + a i f_i=\min\limits_{j\ge i-m}f_j + a_i fi=jimminfj+ai 。而且这里的 j ,也就是决策点, 一定是单调递增的,因为如果存在一个地方是递减的,那么之前的那个 i 做决策时也应该选择这一个 j,而不应该选择更大的 j 。或者可以这样想:j 越大说明后面的选择越宽裕,而优先队列维护的是对于当前的 i 合法的决策点,更新这个队列时把更劣的踢出去,然后把 f i f_i fi 加入队尾。

观察这个式子 f i = min ⁡ j ≥ i − m f j + a i f_i=\min\limits_{j\ge i-m}f_j + a_i fi=jimminfj+ai 可以发现,对于每个 i 它的决策点 j 只作用于左边那一块,右边的 a i a_i ai 不受 j 影响,这是为什么可以用单调队列优化的原因。



分治优化dp

如果右边的 a i a_i ai 变成了 a ( i , j ) a(i,j) a(i,j) ,单纯地单调队列就优化不了了,因为 a 这一部分处于不断变化之中。对于这种情况: f i = min ⁡ 0 ≤ j < i { g j + a ( i , j ) } f_i=\min\limits_{0\le j<i}\{g_j+a(i,j)\} fi=0j<imin{ gj+a(i,j)} ,而且满足决策单调性,要么用二分栈,不过我更喜欢用分治去做。

因为满足决策点调性,假如当前我要处理的是 f [ l , . . . , r ] f[l,...,r] f[l,...,r],并且可能的决策区间为 [ L , R ] [L,R] [L,R] ,那么我们可以定义一个 m i d = ( l + r ) / 2 mid=(l+r)/2 mid=(l+r)/2,然后在 [ L , m i d ] [L,mid] [L,

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值