jzoj4726. 【NOIP2016提高A组模拟8.22】种花 贪心+堆

题目要求在环形排列的数值中选择不相邻的M个点,使得它们的和最大。通过贪心策略,使用大根堆选取最大值,但关键在于设计撤销操作:选取一个最大值后,删除其相邻的两个数,更新该值为相邻数之和与原值的差。这种操作确保了每次选择的最优性。预处理链表用于处理无解情况。
摘要由CSDN通过智能技术生成

这题思路很巧妙,要借鉴。
题意:给你一个环,选出M个点,任意两个互不相邻,要求总和最大。
一开始想的dp,设f[i][0/1]表示i选不选的最大总和,然后发现i的取值基本上能和他前面所有的值都有关联,由于是个环,所以dp你连预处理都会炸。。如果是个序列就可以这么做,不过在后面复制一遍然后用单调队列优化好像也可以,但那就太不优美了其实是我懒得打
那么我们可以贪心,把所有的数加入大根堆,每次取出最上面的,但是这样肯定不是最优秀的,我们可以手动处理出一种撤销操作,这是本题的核心所在:
取出一个数累加到答案以后,把他相邻的两个删除掉,把取出的这个值变为左右之和与这个值的差,但是这个数是可以重新选的。这个操作什么意思呢?
就是说,删除掉旁边两个说明旁边两个不能选,如果有一次选中了,说明这个数没改变之前的值不是最优的,那么就是选旁边两个,此时恰好选了两次,又把原来的数给减掉了,不得不说非常的妙。
要提前预处理一个链表,无解的情况随便判断一下就好了。。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#d
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值