AC code
import os
import sys
import heapq
a = []
b = []
n,k = map(int,input().split())for _ in range(n):x,y = map(int,input().split())a.append(x)b.append(y)
q = []# 第一种情况:不打第n个怪兽# 将前n-1个第一次所需能量加入堆
for i in range(n-1):heapq.heappush(q,(a[i],i))t = k
ans = 0
while t > 0:
# 每次从堆中弹出最小的一个w,i = heapq.heappop(q)
#然后弹入第二次以后击打所需能量heapq.heappush(q,(b[i],i))
#答案加上该能量ans += w
#次数减一t -= 1# 第二种情况:考虑打第n个怪兽
ans2 = 0
#因为前n-1个一定要打,所以要打到n就必须保证击打次数大于等于n
if k >= n:
#因为前n-1个一定要打,所以先把所有第一次击打所需能量加和,
#然后再加上所有第二次以后击打所需能量的最小值*剩余击打次数ans2 += sum(a) + (k-n) * min(b)# 取最小值
if k >= n:print(min(ans,ans2))
else:print(ans)
感觉这道题除了使用了heapq(堆排列)之外,没有使用其他的数据结构知识。
背景知识
在介绍堆排列之外,先补充一些有关大根堆、小根堆的知识
大根堆
每个结点的值都大于其左孩子和右孩子结点的值,称之为大根堆。
小根堆
每个结点的值都小于其左孩子和右孩子结点的值,称之为小根堆。
结合上述图片可直观看出来。
我们将上面图片按照标号进行映射,可以获得对应的数组如下图所示(注意,此方法是一个重要的过程,涉及到如何将图转化为程序代码,也是我原来一直困惑的地方)
如上图,成功将树的形式转换成了数组(列表)形式了。
堆的特点就是FIFO(first in first out)先进先出。
堆在接收数据的时候先接收的数据会被先弹出。
栈的特性正好与堆相反,是属于FILO(first in/last out)先进后出的类型。
heapq库常见函数及用法
简单了解了大小根堆后,对于heapq库大家应该有更好的理解了。
首先,介绍一下heapq的用法。
heapq属于Python的一个内置库,里面
heappush函数
import heapq item=[1,56,7,54,33] heapq.heappush(item,10) print(item)[1, 56, 7, 54, 33, 10]Process finished with exit code 0
上述代码可知,heappush函数对应就是尾插法插入堆中新元素。
heappop函数
import heapq item=[1,56,7,54,33] heapq.heappop(item) print(item)[7, 56, 33, 54]Process finished with exit code 0
将heap的最小值pop出heap,heap为空时报IndexError错误.
此处有一个注意事项,将最小值pop出堆后,会出现原item顺序改变的情况,why?
`heapq.heappop()` 函数在 Python 中会从堆中移除并返回最小的元素。然而,它不保证保持原始顺序。你观察到顺序变化的原因是因为 `heapq` 模块维护堆属性,即最小的元素始终位于根部,但不保证剩余元素的顺序。
当你执行 `heapq.heappop(item)` 时,最小的元素(在这里是 `1`)从堆(`item` 列表)中移除,并且堆属性被恢复。这个操作可能涉及重新排序列表中的元素以保持堆结构,从而导致与原始列表不同的顺序。
如果你想在移除元素时保持原始顺序,你应该使用其他方法,比如在使用堆操作之前对列表进行排序,或者维护一个单独的列表来保存原始顺序。
heappushpop(heap,item)
不再过多解释,两个参数,一个进一个出
pop出heap中最小的元素,推入item。
import heapq item=[1,56,7,54,33] heapq.heappushpop(item,12) print(item)[7, 56, 12, 54, 33]Process finished with exit code 0
以上就是常见的heapq库中函数相关用法。
本题思路
首先考虑在不击败最后一个boss的情况下:
每种怪兽只打一次,对应所需要的能量值为多少。最后再求出对应继续打怪兽,(消灭第二次),直到对应龙之泪达到所需要求。
第二类情况,考虑消灭最后一只龙的情况,这时需要特判,考虑打最后一只怪兽的条件,对应要求n-1只怪兽要全部消灭至少一次。即总打击次数>=n,然后再加上所有第二次以后击打所需能量的最小值*击打次数。
最终将两类情况对应的能量消耗取最小值即为最终结果。
不知各位道友看完此篇博客之后,有没有变得念头通达了呢?【手动狗头】
参考链接:
堆排序及python中heapq堆详解_heapq 用法 实现大根堆-CSDN博客
Python内置的heapq模块简析_python heappush 指定排序-CSDN博客