用最高分做平衡括号
Posted
技术标签:
【中文标题】用最高分做平衡括号【英文标题】:Make balance bracket with highest score 【发布时间】:2022-01-04 22:28:53 【问题描述】:问题:
给定一个整数数组 A 和分数 S = 0。对于数组中的每个位置,您可以执行以下操作之一:
放置一个“(”。分数将是 S += Ai 放置一个“)”。分数将是 S -= Ai 略过为了使括号平衡,您可以获得的最高分是多少?
限制:
|艾| 数组 A 的大小:P/S:
我尝试了很多方法,但我最好的方法是使用 O(3^n) 的蛮力。有没有办法在 O(n.logn) 或更短的时间内解决这个问题?
【问题讨论】:
这是在线测试的地方吗?数组可以有多大?有时间限制吗? @KellyBundy 它来自我学校的一个古老的私人比赛。我刚刚添加了限制 【参考方案1】:您可以使用二维数组highest_score在O(n2) 时间内完成此操作,其中 highest_score[i][b] 是在位置 i 与 b 之后可获得的最高分数 开放括号尚未关闭。每个元素 highest_score[i][b] 仅取决于 highest_score[i -1][b-1]、highest_score[i-1][b]和highest_score[i-1][b+1](当然还有A[i]),因此每一行 highest_score[i] 可以在 O(n) 时间内从上一行highest_score[i-1],最后的答案是highest_score[n][0]。
(注意:使用 O(n2) 空间,但由于 highest_score 的每一行取决于仅在上一行,您实际上可以通过重用行在 O(n) 中做到这一点。但渐近运行时复杂度将是相同的。)
【讨论】:
由于数组 A 的大小 我觉得你也需要考虑highest_score[i−1][b]
,不是吗?
@KellyBundy:感谢您指出这一点;我忘记了“跳过”是一种选择! (虽然我想这没有实际意义,但现在已经发布了更好的答案?)
我不认为它没有实际意义,它至少对testing 正确性的另一个答案有用:-)【参考方案2】:
您可以在O(n log n)
时间内使用最大堆来执行此操作。
首先,消除操作中的不对称性。假设我们以-sum(A)
的运行总和开始,而不是有左方括号和右方括号,即所有右方括号。现在,对于 A 中的每个元素,我们可以将其添加到我们的运行总和中,可以是 0、1 或 2 次,分别对应于留下一个封闭的括号、删除封闭的括号或添加一个开放的括号。平衡约束现在表示,在处理了第一个 k
元素后,我们有:
-
至少添加了
k
,对于所有整数k
,
我们增加了length(A)
的总数。
我们已将最后一个元素添加到我们的总和中,无论是零次还是一次。
假设在处理完第一个k
元素后,我们添加了k
,并且我们拥有所有此类配置的最高分。我们可以将其扩展到第一个 k+1
元素的最大分数配置,并贪婪地添加 k+1
。我们有一个新的选择,可以将k+1-th
元素添加到我们的总和中最多两次,但现在最多只能添加一次。只需选择尚未两次添加到总和中的最大可见元素,并将其添加到总和中:这也必须是最大分数配置,或者我们可以显示旧配置也不是最大的。
Python 代码:(所有值都取反,因为 Python 只有一个最小堆)
def solve(nums: List[int]) -> int:
"""Given an array of integers, return the maximum sum achievable.
We must add k elements from nums and subtract k elements from nums,
left to right and all distinct, so that at no point have we subtracted
more elements than we have added.
"""
max_heap = []
running_sum = 0
# Balance will be 0 after all loop iterations.
for value in nums:
running_sum -= value # Assume value is subtracted
heapq.heappush(max_heap, -value) # Option to not subtract value
heapq.heappush(max_heap, -value) # Option to add value
# Either un-subtract or add the largest previous free element
running_sum -= heapq.heappop(max_heap)
return running_sum
【讨论】:
以上是关于用最高分做平衡括号的主要内容,如果未能解决你的问题,请参考以下文章