[M贪心] lcLCP30. 魔塔游戏(STL优先队列+堆+贪心)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M贪心] lcLCP30. 魔塔游戏(STL优先队列+堆+贪心)相关的知识,希望对你有一定的参考价值。
1. 题目来源
链接:LCP 30. 魔塔游戏
2. 题目解析
挺不错的一道贪心问题。
思路:
- 首先顺序累加所有怪物血量,在血量初始值为 1 时,若累加完毕, s u m ≤ 0 sum \\le0 sum≤0 则说明怎么调整也是无法保证走完所有房间且血量符合要求的。返回 -1 即可。反之,一定可以通过调整走完所有房间,大不了就将所有的负数全部放到最后,就可以了。
- 但是如何保证调整次数最少呢?一定不能见到一个负数就操作一次吧。
- 贪心调整思路如下:
- 每次在我们血量 b l o o d ≤ 0 blood \\le 0 blood≤0 的时我们进行调整。调整时,将之前我们遇到的对我们伤害最大的怪物放到最后。即负数最小的,也就是负数中绝对值最大的怪物放到最后。因为之前遇到过,血量已经被他扣了,在调整时,要将之前被这个怪物扣的血量补充回来。直到依次将扣血最大的怪物向后调整,补充血量到 > 0 \\gt0 >0 后,再依次向后走。
- 血量初始为 1 ,为题目要求。顺序遍历怪物,记录遇到的负血量的怪物,由于需要动态的记录这些负血量怪物的最大值,所以需要使用优先队列。
- 每遇到一个怪物,不论血量正负,都和当前的血量 b l o o d blood blood 进行累加。且记录负血量怪物进小顶堆,在此使用技巧,负值可以添加负号变为正值,然后放入大顶堆,达到和小顶堆同样的效果。注意出堆时,需要再补充回一个负号。
- 当 b l o o d ≤ 0 blood\\le0 blood≤0 时,一定是之前遇到了负血量怪物,那么就要将堆中这些负血量怪物,按照扣出血量大小依次出堆,补充给 b l o o d blood blood,直到将 b l o o d blood blood 补充回 > 0 \\gt0 >0 的状态。然后就不必再调整了。
- 在此,直接取堆顶元素补充给血量即可,然后直接将堆顶元素出堆,不需要再保留该怪物的血量作记录。因为一定可以经过调整遍历完所有怪物房间,且只会有负血量怪物调整到末尾。所以,我们在血量见底时,假装的没遍历,调整后血量补充,等价于跳过这个扣血最大的怪物,将其放到最后。那么,遍历完之后我们剩余的血量 b l o o d blood blood,也是一定可以将最后这些调整的连续负血量怪物遍历完的。最后只需要返回最小的调整次数即可,剩余血量,就是一开始累加的 s u m sum sum。
总结如下:
- 一开始累加所有怪物血量,若 ≤ 0 \\le0 ≤0,则返回 -1,无法调整。
- 反之,一定可以调整。顺序遍历所有怪物,累加血量 b l o o d blood blood,并将负血量怪物记录进优先队列,用以动态计算扣血最大的负血量怪物。当血量 b l o o d ≤ 0 blood\\le0 blood≤0,则从堆中依次弹出之前遇到的扣血最大的怪物用以回血。这样一来,之前扣的血,现在再加上,等价于没遍历这个怪物,等价于将其调整到最后,则调整次数 +1。
- 当遍历到数组末尾时,该末尾后面全是调整过来的负血量怪物,已经不需在此调整。一定保证当前剩余血量可以遍历完这些连续的负血量怪物,故直接返回调整次数即可。
注意开 LL
…
- 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)。
- 空间复杂度: O ( n ) O(n) O(n)
代码:
class Solution {
public:
int magicTower(vector<int>& nums) {
typedef long long LL;
LL sum = 1;
for (int x : nums) sum += x;
if (sum <= 0) return -1;
LL blood = 1, res = 0;
priority_queue<int> q;
for (int x : nums) {
if (x < 0) q.push(-x);
blood += x;
while (blood <= 0) {
blood += q.top(); q.pop();
res ++ ;
}
}
return res;
}
};
以上是关于[M贪心] lcLCP30. 魔塔游戏(STL优先队列+堆+贪心)的主要内容,如果未能解决你的问题,请参考以下文章
[M贪心] lc1353. 最多可以参加的会议数目(扫描线+STL优先队列)
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博(