https://leetcode.com/problems/maximum-running-time-of-n-computers/
好题目,题干问题本身比较有使用价值,就是一个统筹策划的问题。
题目的解法也用到了归约的思想,设计的还是非常巧妙的。
个人解答
class Solution:
def maxRunTime(self, n: int, bs: List[int]) -> int:
s = sum(bs)
bs.sort()
for x in bs[::-1]:
if x > s // n:
n -= 1
s -= x
return s // n
思路分析
这道题是周赛的最后一题,并没有做出来,看了解答,简直妙啊妙啊。
一开始的思路比较直接:每次都用剩余电量最多的n个,这样就保证不浪费。
但是维护动态变化的最多的n个不是那么容易。
首先想到heap实现,每次pop出n个,-1之后再push回去。
后来想到可以优化,每次不-1,而是直接减到比剩余元素小1。这一定程度可以提高效率,但还是超时了。
所以根据题目中的10^5的数据量,这样的模拟操作是无法接受的,需要换个思路。
理想状况下,电池都能够用完,可以坚持s // n
时间。但如果有n-1
或更少的电池太多了,最后只剩下n-1
个电池,就没办法继续利用了。
而且,电量超过s // n
电池的肯定用不完,那么说明一直用它给一个计算机供电,并不会产生浪费。
于是,问题似乎可以转化为,剩下的电池对于剩下的计算机能够坚持多久。这里还需要论证一下,最多的这个会不会浪费。
其实并不会,因为一个电池不能掰成两截用,这个电池一直给一个计算机供着电。只要其它的能把剩下的计算机供起来,它也能陪得起;反之,如果其它的完不成,它也抽不出身。
所以这个归约是成立的。
直到最后,n == 1
或者剩下的正好平均的时候,剩下的全填上就好了,便是剩下的总量除以当时的n
: s // n
妙啊妙啊!