可撤销贪心

例题见JZOJ4726。

以这一道题为例,我们可以贪心,每一次从剩下可选的数中选出一个最大的,但这样显然是错的。那么怎么办呢?我们可以考虑让贪心变得可撤销。

假设当前我们选了第i个数,那么它的贡献就是a[i]。但是最优解有可能不选它,如果不选它的话,那么就会选它的两侧相邻的点,如果这样选的话贡献就是a[i-1]+a[i+1]。所以要把之前的贪心撤消了,就相当于把ans加上a[i-1]+a[i+1]-a[i]。

具体做法如下:首先把所有a[i]加入一个大根堆里。再记录一下每一个数的前驱和后继,即l[i]=i-1,r[i]=i+1(当然,l[1]=n,r[n]=1)。然后取m次。每一次取堆顶。假设当前取出的是a[i],那么我们把a[l[i]]+a[r[i]]-a[i]加入大根堆,再把l[i]和r[i]删掉(也就是更新前驱和后继)。这样做就可以了。

为什么要记录前驱和后继呢?因为如果我们要撤销对a[i]的贪心,那么就要对a[i]的前驱的后继做操作,也就相当于把这三个点缩成一个点,所以要记录前驱和后继。

总结:

可撤销贪心就是把不选这一个点的贡献减去选这一个点的贡献的值加入所有选择方案里,但是要注意有关的点要缩成一个点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值