魔塔游戏

本文介绍了解决魔塔游戏中血量管理问题的策略,利用贪心算法和优先队列,当血量低于1时将扣血最多的怪物房间调整至最后,计算最少调整次数。若无法完成所有房间,返回-1。
摘要由CSDN通过智能技术生成

1.题目

这道题是2024-2-6的签到题,题目难度中等。

考核的知识点为:贪心算法+优先队列。

题目链接:魔塔游戏

小扣当前位于魔塔游戏第一层,共有 N 个房间,编号为 0 ~ N-1。每个房间的补血道具/怪物对于血量影响记于数组 nums,其中正数表示道具补血数值,即血量增加对应数值;负数表示怪物造成伤害值,即血量减少对应数值;0 表示房间对血量无影响。

小扣初始血量为 1,且无上限。假定小扣原计划按房间编号升序访问所有房间补血/打怪,为保证血量始终为正值,小扣需对房间访问顺序进行调整,每次仅能将一个怪物房间(负数的房间)调整至访问顺序末尾。请返回小扣最少需要调整几次,才能顺利访问所有房间。若调整顺序也无法访问完全部房间,请返回 -1。

2.思路

其实对于优先队列的问题,它其实已经包含了贪心算法的思想在里面,这道题也不例外。对于这道题,我们需要弄明白下面几个问题:

什么是优先队列?

优先队列相比于普通的队列,它会根据某种规则自动排序,比如根据队列元素的大小进行排序,小的在前面或者大的在前面。

通俗来讲,也有一个结构和它类似——小根堆。小根堆的特性是元素小的在上面,元素大的在下面(这里仅按照元素大小排序)。

如何应用到这题?

那我们如何使用优先队列在这题呢?根据题目要求,我们不到万不得已的时候不会移动怪物房间,因此我们只需要在当前的血量小于1的时候移动怪物房间,那移动哪一个怪物房间呢?这就提到我们的优先队列了,我们将扣血最多的怪物房间移动到队列尾部就行了,这样就即解决我们的血量问题,也能够使得利益最大化(贪心思想)。

解题思路

在我们对有限队列有了一定的认知后,我们在想怎么应用这题。我的思路是这样,这题的要求是尽可能最小移动次数来使得怪物房间移动到队尾。因此我们需要考虑两种情况:

  1. nums数组和小于0
  2. nums数组和大于0

对于第一种情况相信我们很容易理解,你都总和小于0了,说明无论怎么花里胡哨的移动,他最终都会ganmeover。

因此我们的算法只需要考虑第二种情况。首先,我们初始并定义一个小根堆,然后定义一个遍历blood作为血量,ans为操作次数。然后开始遍历数组,如果当前的num值小于0,说明这个房间是怪物房间,我们将它加入到小根堆(优先队列)里面。然后先加入到当前血量中,如果加入到当前血量后小于1,说明有个怪物房间需要移动到队尾了,因此这里需要移动扣血最多的怪物房间到队尾。

3.代码

import heapq
from typing import List
class S:
     def f(self,nums:List[int])->int:
          # 如果数组总和小于0,则返回-1
          if sum(nums) < 0:
               return -1
          # 操作次数
          ans = 0
          # 小根堆
          q = []
          # 血量
          blood = 1
          # 初始化为小根堆
          heapq.heapify(q)
          # 遍历nums数组
          for num in nums:
               # 如果当前的值小于0,则加入小根堆
               if num < 0:
                    heapq.heappush(q,num)
               # 加入到血量
               blood += num
               # 如果血量小于1,说明需要移动房间
               if blood < 1:
                    # 移动扣血最多的房间
                    blood -= heapq.heappop(q)
                    # 操作次数+1
                    ans += 1
          return ans

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小人物₍˄·͈༝·͈˄*₎◞ ̑̑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值