【总结】二叉堆(7.20)
一.概述
堆一般有两个重要的操作,put(往堆中加入一个元素)和get(从堆中取出并删除一个元素)。put一般用来建堆和维护堆,get则是得到最小值。
堆在NOIP竞赛中应用广泛,常用与快速查询最大(最小值),优化各种算法(如:最短路算法、DP算法),是一种效率高,应用广泛的数据结构。
显然,堆只能以一个关键字作为顺序,若一个决策涉及时间和权值,那就必须转换问题,使时间(或权值)的条件弱化,这样就可以愉快地贪心了
下面以大根堆为例:
二.题目
http://222.180.160.110:1024/contest/630
A.堆
题目描述
如题,初始小根堆为空,我们需要支持以下3种操作:
操作1: 1 x 表示将x插入到堆中
操作2: 2 输出该小根堆内的最小数
操作3: 3 删除该小根堆内的最小数
解析:板子题
B.鱼塘钓鱼(fishing)
解析:我们可以发现,假设能钓到鱼的数量仅和已钓鱼的次数有关,且每次钓鱼的时间都是整数分钟。 则每次钓鱼都要取当前最大值。但本题路程是变量,可以枚举到达的最远鱼塘,显然不会走回头路(因为与钓鱼先后无关),我们可以加入[1,i]的鱼塘,令 t = m − l [ i ] t=m-l[i] t=m−l[i],其中 l l l表示路程所花费时间。每次从二叉堆中取出并删除最大值,修改后再加入,重复 t t t次就得到了当前最大价值。
二叉堆其实很擅长于求前m个大的决策,我们通常是先求最大,再求次大,以此推广。或者先求局部最优解,再缩小问题规模,直到问题解决。(贪心思想)
C.[CTSC2007]数据备份Backup
显然可以有70pts的dp代码:
不难想到, 为了使布线长度尽量小,每对布线的办公楼一定是相邻的
所以我们可以在读入时计算差分数组保存每相邻两个办公楼的距离
这样问题转化为, 在差分数组中找k个数,满足k个数之和最小且互不相邻
设差分数组为b[], 其中最小的数为b[i]
显然最优解必定是一下其中一种
1.包含b[i]以及除b[i-1]和b[i+1]的数
2.包含b[i-1]和b[i+1]以及除b[i],b[i-2],b[i+2]
从这一点扩展, 可以先取b[i],并以b[i-1]+b[i+1]-b[i]替换,
然后在新数列中继续重复k-1次得到最后结果
这样若b[i]不属于最优解,则b[i-1]+b[i+1]-b[i]必定被选,满足了上述第二种情况
更具体做法是, 将原差分数组每个值插入堆, 并将数组以链表串起来
每次取堆顶最小值更新答案,并删除该值,
设最小值编号为i, 那么再插入b[ pre[i] ]+b[ nxt[i] ]-b[i], 并更新链表
重复k次即得最优解
__EOF__

本文链接:https://www.cnblogs.com/cqbzly/p/17530416.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」