知乎看到的米哈游算法题_把败怪物所需最少次数_怪物半血会爆炸

知乎看到的米哈游算法题_把败怪物所需最少次数_怪物半血会爆炸
然后去试着实现了一下.

题目描述

具体的描述是这样的
首先是入参
1.若干怪物的血量是正整数,怪物血量变为0时判定死亡。
关键信息或者机制就两个

 2.玩家单次攻击可以对一个怪物造成一点伤害 
 3.怪物生命值削减到最大生命值一半时会对所有怪物造成一点伤害 (这里我默认所有怪包括自身)

然后要求是求出击败所有怪物所需的最小攻击数

思路

这个有个类似的应该是崩铁黑塔的转圈圈 ,
他的机制是我方如果把对面打到半血以下,就触发一次追加攻击,但是如果多个怪物同时到半血以下,也只触发一次(
触发多次也太超模了,毕竟只是四星角色而已)

这里不同的地方是 , 这个是怪物本身触发的一个爆炸效果,给所有怪炸掉一点伤害,而且是可以连环炸的 . 所以有区别.

具体思路就是 ,
如果知道所有怪都得死 , 那么所有怪都得炸 , 那么爆炸次数就是 monsters 数组的长度 length ,
如果所有怪都得炸 , 那么首先先把血量大于length的怪都打到length的血量 , 因为大于length的这部分必定要一下下打 .
(如果在把这些高血量怪物打到length的过程中 , 触发了爆炸,那这个得特殊处理 , 也就是预爆炸 .
如果高血量怪把部分低血量怪物也触发了爆炸,那么也是特殊处理了)
等到把该炸的都炸了 , 剩余的未爆炸的怪物 , 就该考虑下一步了 .

那就是,从最容易炸的开始炸

具体代码


    public static int attackTimes(int[] monsters) {
        Arrays.sort(monsters);
        int length = monsters.length;
        int res = 0;
        int preBoom = 0;
        int lastBoomIndex = length;
        for (int i = length - 1; i >= 0; i--) {
            int curBoomHp = monsters[i] >> 1;
            if (monsters[i] > length) {
                res += monsters[i] - length;
                if (curBoomHp >= length) {
                    lastBoomIndex = i;
                    preBoom++;
                }
                monsters[i] = length;
            }
            monsters[i] = monsters[i] - curBoomHp;
        }
        Arrays.sort(monsters, 0, lastBoomIndex);
        for (int i = 0; i < lastBoomIndex; i++) {
            res += Math.max(monsters[i] - preBoom - i, 0);
        }
        return res;
    }

一个中间想到的但是没法用的情况 .

前言 : 例如 f(n,m) 代表 打死 m个n血怪需要的平a次数 .
某些特殊情况下可以转换为 f(n,m) = (n+1)/2 + f(n-1,m-1) , 也就是动态规划 . 只不过情况比较特殊 ,其他情况不好写代码

中间分析过一下,要不要先根据血量分组 , 得到 key是血量 , value是这个血量的怪物个数的 TreeMap.
然后思路其实和上面差不多 “累计爆炸值” , 但是不同的地方是以一个个小组来的 .
然后在推规律的时候 , 例如 5血怪物有3个 (5,5,5) . 6血怪物有4个(6,6,6,6).
如果把6血怪物的第一个平a3次,只剩下3点血,然后炸一下 , 不就成了 (2,5,5,5) ,
这里的情况是剩下的怪物数量大于血量的情况 , 例如n血量的怪有m个 (代表右边的怪可以炸m次)
也就是 n - ( (n+1)/2 ) - 1 <= m-1 的情况
那么其实状态可以转换为 f(n,m) = (n+1)/2 + f(n-1,m-1)
前提是 n是偶数的情况 , 例如 n = 2a , 这样需要的平a次数就是(2a+1)/2是a次 , n-1时 (2a-1+1)/2 也是a次.

然后最大的问题是要是怪物血量太高数量太大,dp输出是顶不住的 . 而且只使用与正数 , 万一他整个浮点给你这个就没法推了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值