美文网首页
多因素最值问题总结

多因素最值问题总结

作者: madao756 | 来源:发表于2020-06-20 00:01 被阅读0次

    前言:这个标题是我自己取的,我们要找到一个最值,而这个值与多种因素有关,所以我把他叫做「多因素最值问题」

    一般多因素的最值问题都与排序相关,关键是按什么排序,能有更好的策略。

    下面我总结一些我遇到的算法思路

    0X00 单因素排序

    1383. 最大的团队表现值

    首先发现是一个多因素最值问题,尝试两个关键字排序。

    • 如果按照 speed 排序,不好做,没思路,放弃
    • 如果按照 efficiency 排序,就可以建立一个最多 k 大小的堆,固定 e 去遍历所有的方案这样的时间复杂度是 O(nlogn)
    from heapq import heappush, heappop
    
    class Solution:
        def maxPerformance(self, n: int, speed: List[int], efficiency: List[int], k: int) -> int:
            mod = 10 ** 9 + 7
            res, minHeap, m = 0, [], [(v1, v2) for v1, v2 in zip(efficiency, speed)]
            m.sort(reverse=True)
            # print(m)
            sums = 0
    
            for e, s in m:
                heappush(minHeap, s)
                sums += s
                if len(minHeap) > k: sums -= heappop(minHeap)
                res = max(res, e * sums)
            
            return res % mod
            
    

    这里有个比较坑的地方,就是如果是比较的话,中间计算过程是不能取余数的。

    0X01 组合因素排序

    125. 耍杂技的牛

    跟上题一样同样是双因素最值问题,但是这题的最优策略不能按照单因素去排序,而是将这两个因素去组合。设一头牛 i 的重量是 w[i],强壮程度是 s[i]。

    这种题你没做过是想不出来的。

    所以要把这种题当成「模板题」。

    首先,按照经验来看这里的「最大风险值」的计算方法不涉及 * / 在构造的时候就不用选择 * /。

    我们构造按照 w[i] + s[i] 从小到大的排序的方法(按照感觉来想也是这样,重量越大,越强壮的牛放在越后面),构造牛的序列,即 w[i] + s[i] 越小的放在前面。

    现在通过「微扰法」证明:

    假设有这么两头牛 w[i] + s[i] > w[i+1] + s[i+1]。第 i 头牛放在了上面,假设第 i 头牛上面的重量是 w_all,那么对于这两头牛来说,我们可以列出一个表:

    风险
    i w_all - s[i]
    i+1 w_all + w[i] - s[i+1]

    「微扰法」的核心就是交换,不影响其他的值。于是我们将两者交换,得出一张新表

    风险(交换前) 风险(交换后)
    i w_all - s[i] w_all + w[i+1] - s[i]
    i+1 w_all + w[i] - s[i+1] w_all - s[i+1]

    这个题要我们求的是使最大风险值最小,现在证明交换后的最大风险值会减小:

    由于 w_all + w[i] - s[i+1] > w_all - s[i] 所以交换前的最大风险值是 w_all + w[i] - s[i+1] 并且 w_all + w[i] - s[i+1] > w_all - s[i+1] 以及 w_all + w[i] - s[i+1] > w_all + w[i+1] - s[i]

    所以交换后的最大风险值一定是降低的,故牛从上到下的排序一定是按 w[i] + s[i] 的升序排序的。

    我们再说一个难题,谷歌 2019 年 B 轮的题目:

    734. 能量石

    这里有三个因素,s[i] 吃完能量石的时间, e[i] 能量石最初的能量, l[i] 能量石每秒消耗的能量。有了前一题的基础我们知道,这是一道「多因素最值问题」,和三个因素有关。

    不能直接给出策略,但是我们可以来算一算(已过去 t 时间):

    能量石 获得的能量(交换前) 获得的能量(交换后)
    i e[i] - t * l[i] e[i] - (t + s[i+1]) * l[i]
    i+1 e[i+1] - (t+s[i]) * l[i+1] e[i+1] - t * l[i+1]

    计算吃这两块石头获得的能量:

    获得的能量(交换前) 获得的能量(交换后)
    e[i] + e[i+1] - t * (l[i] + l[i+1]) - s[i] * l[i+1] e[i] + e[i+1] - t * (l[i] + l[i+1]) - s[i+1] * l[i]

    要想交换后的能量更高即:s[i+1] * l[i] < s[i] * l[i+1] => l[i+1] / s[i+1] > l[i] / s[i]

    即我们的策略是:l[i] / s[i] 越大的先吃。

    0X02 总结

    对于多因素的最值问题,我们要做到的是:

    • 判断题目是多因素最值问题
    • 看能不能通过简单因素判断(常识)
    • 通过交换两个相邻的,且交换后要比交换前要好,判断出我们到底应该用什么因素排序

    相关文章

      网友评论

          本文标题:多因素最值问题总结

          本文链接:https://www.haomeiwen.com/subject/ptmixktx.html