题解 | #请客吃饭#(Python3)
请客吃饭
https://www.nowcoder.com/practice/4250a369235e414ba9128bb23ff4fcf5
# 定义一个足够大的数,代表无穷大 INF = int(9e18) # 读取朋友总数n和希望达到的愉悦值k n, k = map(int, input().split()) # 读取每个朋友的财富值 ai = list(map(int, input().split())) # 读取每个朋友可以获得的愉悦值 bi = list(map(int, input().split())) # 将财富值和愉悦值组合,并添加一个哨兵元素(0, 0)以处理边界情况 a = [(0, 0)] a.extend(list(zip(ai, bi))) # 按照财富值对朋友进行排序 a.sort() # 初始化当前愉悦值总和和最小隔阂值 res = 0 ans = INF # 初始化双指针的左边界 left = 0 # 遍历每个朋友,右边界从1开始到n结束 for right in range(1, n + 1): # 累加当前朋友的愉悦值 res += a[right][1] # 当当前愉悦值总和大于等于k时,尝试缩小窗口 while left < right and res >= k: # 更新最小隔阂值为当前窗口内财富值的最大差异 ans = min(ans, a[right][0] - a[left + 1][0]) # 移动左边界,并减去左边界的愉悦值 left += 1 res -= a[left][1] # 如果最小隔阂值仍然是无穷大,说明无法达到k的愉悦值,输出-1 if ans == INF: print(-1) else: # 否则,输出最小隔阂值 print(ans)
缩小窗口的条件是什么,为什么要缩小窗口
缩小窗口的条件是当前累积的愉悦值 res
大于等于目标愉悦值 k
,并且左指针 left
小于右指针 right
。具体来说,代码中的条件是while循环的条件
为什么要缩小窗口,原因如下:
- 优化隔阂值:当累积的愉悦值 res 已经达到或超过目标值 k 时,我们不需要包含所有的朋友来达到这个愉悦值。通过缩小窗口(即减少包括的朋友数量),我们可以尝试找到一个更小的财富差异(隔阂值),从而优化最终的结果。
- 贪心策略:根据题目要求,我们需要最小化隔阂值。如果我们保持窗口不变,即使愉悦值已经满足要求,我们也可能不是在最小化隔阂值。通过缩小窗口,我们可以逐步排除财富值较高且愉悦值较低的朋友,从而可能找到一个更小的隔阂值。
- 减少不必要的计算:一旦愉悦值达到目标,就没有必要继续增加更多的朋友,因为这样只会增加隔阂值。通过缩小窗口,我们可以减少不必要的计算,提高算法的效率。
- 维持愉悦值:在缩小窗口的过程中,我们需要确保缩小后的窗口仍然能够满足愉悦值至少为 k 的条件。这是通过在缩小窗口时减去左边界的愉悦值来实现的。
综上所述,缩小窗口是为了在满足愉悦值要求的前提下,寻找最小的隔阂值,同时提高算法的效率。
为什么这道题目可以使用贪心策略
这道题目可以使用贪心策略的原因在于,问题的性质允许我们通过局部最优的选择来达到全局最优解。以下是几个关键点说明为什么贪心策略适用于这个问题:
- 单调性:如果选择财富值较小的朋友可以带来更大的愉悦值,那么在满足愉悦值至少为 k 的条件下,我们总是倾向于选择财富值较小的朋友。这是因为财富值较小的朋友更有可能减少财富差异(隔阂值),而不会牺牲愉悦值。
- 不可撤销性:一旦我们选择了某个朋友,我们就不再考虑将其从选择中移除。这意味着我们的选择是单向的,一旦做出选择,就无法回头。这种不可撤销性使得贪心策略更为适用,因为我们不需要考虑之前的选择对后续选择的影响。
- 最优子结构:问题的最优解包含了其子问题的最优解。在这个问题中,如果我们找到了一个财富差异最小的子数组,那么这个子数组中的任何更小子数组也将是财富差异最小的。这意味着我们可以通过局部最优的选择来构建全局最优解。
- 子问题的独立性:在选择朋友时,我们只关心财富值和愉悦值,而不关心朋友之间的其他关系。这意味着每个朋友的选择都是独立的,我们可以单独考虑每个朋友对最终结果的影响。
具体来说,以下是贪心策略的应用:
- 排序:首先,我们将朋友按照财富值进行排序。这样,我们可以确保在选择朋友时,财富值的差异最小化。
- 累积愉悦值:我们从财富值最小的朋友开始,逐步增加朋友的数量,并累积愉悦值,直到愉悦值达到或超过
k
。 - 最小化隔阂值:在累积愉悦值的同时,我们记录财富值的最大差异。当愉悦值达到或超过
k
时,我们尝试通过减少朋友数量来最小化这个财富差异。
通过这种方式,贪心策略允许我们快速找到满足条件的解,同时确保解是最优的。在这个问题中,贪心策略的有效性在于我们总是可以通过选择财富值较小的朋友来减少财富差异,而不需要考虑所有可能的组合。
#15天刷题#