问题描述
小 C 来到了一家饭馆,这里共有 n 道菜,第 i 道菜的价格为 a_i。其中一些菜中含有蘑菇,s_i 代表第 i 道菜是否含有蘑菇。如果 s_i = '1',那么第 i 道菜含有蘑菇,否则没有。
小 C 希望点 k 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 m 道菜含有蘑菇。小 C 想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出 -1。
测试样例
样例 1
输入:
s = "001", a = [10, 20, 30], m = 1, k = 2输出:
30
样例 2
输入:
s = "111", a = [10, 20, 30], m = 1, k = 2输出:
-1
样例 3
输入:
s = "0101", a = [5, 15, 10, 20], m = 2, k = 3输出:
30
解题思路分析
这道题的核心是从道菜中选择道,使得总价格最低,同时满足含有蘑菇的菜品数量不超过。以下是详细思路:
步骤 1:分类菜品
根据是否含有蘑菇,将菜品分为两组: - 含有蘑菇的菜品(记为 with_mushroom); - 不含蘑菇的菜品(记为 without_mushroom)。
步骤 2:排序
对两组菜品分别按价格升序排序。这样可以方便地从每组中选出价格最低的菜品。
步骤 3:前缀和优化
为了快速计算选取某些菜品的总价格,使用前缀和技术。例如,排序后的菜品价格为 [5, 7, 10],前缀和为 [0, 5, 12, 22],表示从前道菜中选取的总价格。
步骤 4:组合选择
遍历可能选择的蘑菇菜品数量 ,计算对应的不含蘑菇菜品数量为 。
检查是否满足以下条件:
- 道含蘑菇菜品的总数不超过 ;
- 道不含蘑菇菜品的总数不超过其总数量。如果满足条件,计算总价格并更新最小值。
步骤 5:返回结果
如果存在满足条件的组合,返回最小价格;否则返回 -1。
代码实现
def solution(s: str, a: list, m: int, k: int) -> int:
# 将菜品分类
with_mushroom = [] # 含蘑菇的菜品价格
without_mushroom = [] # 不含蘑菇的菜品价格
for i in range(len(s)):
if s[i] == '1':
with_mushroom.append(a[i])
else:
without_mushroom.append(a[i])
# 对价格排序
with_mushroom.sort()
without_mushroom.sort()
# 计算前缀和
prefix_with_mushroom = [0] * (len(with_mushroom) + 1)
prefix_without_mushroom = [0] * (len(without_mushroom) + 1)
for i in range(1, len(prefix_with_mushroom)):
prefix_with_mushroom[i] = prefix_with_mushroom[i - 1] + with_mushroom[i - 1]
for i in range(1, len(prefix_without_mushroom)):
prefix_without_mushroom[i] = prefix_without_mushroom[i - 1] + without_mushroom[i - 1]
# 遍历选取蘑菇菜品的数量
min_cost = float('inf')
for mushrooms in range(min(len(with_mushroom), m) + 1):
# 剩余需要选的不含蘑菇的菜品数量
non_mushrooms = k - mushrooms
# 检查是否可行
if non_mushrooms >= 0 and non_mushrooms <= len(without_mushroom):
# 计算总价格
total_cost = prefix_with_mushroom[mushrooms] + prefix_without_mushroom[non_mushrooms]
min_cost = min(min_cost, total_cost)
return min_cost if min_cost != float('inf') else -1
总结
1. 贪心算法
贪心思想:通过排序后优先选择价格最低的菜品,逐步尝试组合以满足条件。
2. 前缀和
使用前缀和快速计算前道菜的总价格,减少重复计算,提升效率。
3. 边界条件
- 若或,直接返回 -1。
- 如果两组菜品的数量都不足以满足,则无法实现要求。
4. 优化时间复杂度
排序的复杂度为,遍历组合的复杂度为。整体复杂度为,适合大规模数据处理。