算法:清空所有怪兽需要的AOE次数

题目描述

给定两个非负数组x和hp,长度都是N,再给定一个正数rangex有序

  • x[i]表示i号怪兽在x轴上的位置;
  • hp[i]表示i号怪兽的血量
  • range表示法师如果站在x位置,用AOE技能打到的范围是:[x-range,x+range],被打到的每只怪兽损失每次1点血量

返回要把所有怪兽血量清空,至少需要释放多少次AOE技能?

题目解析

贪心

我们先假设hp是紧贴在站在一起的(也就是先不看X),假设其hp如下:
在这里插入图片描述
因为最终要把所有的怪兽都杀死。

  • 我们先看第一个怪兽,其hp为5。那么不管这个怪兽是怎么死的,其一定要被AOE覆盖它5次。
  • 我们每次AOE以它为起点,放五次,那么hp数组变为:

在这里插入图片描述

  • 然后我们再找下一个大于0的怪兽,以它作为AOE的起点,以最少的次数去杀死它,得到如下:
    在这里插入图片描述

  • 然后我们再找下一个大于0的怪兽,以它作为AOE的起点,以最少的次数去杀死它,得到如下:

在这里插入图片描述

  • 下一个没有大于0的怪兽了,完毕。最终得到
    在这里插入图片描述

贪心方法无需证明,那怎么验证它的正确性呢?写一个暴力全排列的方法,通过实现对比它们的答案是不是相同,以得到。

如果我们要把x[i]和hp[i]总和起来看呢?x[i]只会影响AOE能够扫描到的怪兽范围,但是贪心策略是不变的。问题: 每次以i怪兽为起点,那么哪些位置能够被波及到呢?

  • i位置的怪兽的位置是 x [ i ] x[i] x[i],加上AOE的范围是 x [ i ] + L x[i] + L x[i]+L,那么本次AOE怪兽范围是 x [ i ] . . . . . . . x [ i ] + L − 1 x[i].......x[i] + L - 1 x[i].......x[i]+L1
  • 因为 x [ i ] x[i] x[i]是从小到大的,我们只需要在x[i]数组上从x[i]位置开始,遍历(因为每一个怪都要掉血,所以直接扫描,不二分)到第一个等于 x [ i ] + L − 1 x[i] + L - 1 x[i]+L1停止(怪兽是不会堆在一起站的,一个位置只能站一个怪兽,所以下一个位置一定大于 x [ i ] + L − 1 x[i] + L - 1 x[i]+L1,所以我们遍历到 x [ i ] + L − 1 x[i] + L - 1 x[i]+L1就停止)
  • i位置的怪兽的位置是AOE次,每次掉1滴血,所以每次区间内的数都要减少AOE滴血

在上面贪心方法中,我们针对每一个区间范围内的数要做:

  • 在全部区间中查询第一个大于0的数(区间查询)
  • 在指定区间内将所有数都减少n(区间修改)

所以,可以用线段树来优化上面过程。问题是怎么在全部区间中查询第一个大于0的数(区间查询):

  • 先在一个范围上所有数字都减少n,剪完之后在线段树中查:
    • i+1 ~ i + 1范围内是不是 大于0的
    • i+2 ~ i + 2范围内是不是 大于0的
    • i+3 ~ i + 3范围内是不是 大于0的
  • 如果找到了第一个大于0的,那么就以这个为起点去AOE
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值