题面
小C来到了一家饭馆,这里共有 nn 道菜,第 ii 道菜的价格为 a_i。其中一些菜中含有蘑菇,s_i 代表第 ii 道菜是否含有蘑菇。如果 s_i = '1',那么第 ii 道菜含有蘑菇,否则没有。
小C希望点 kk 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 mm 道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出-1。
问题分析
我们需要从 n 道菜中选择 k 道菜,同时确保以下两个条件:
- 至少选择
k道菜; - 选择的菜中最多只能包含
m道含有蘑菇的菜。
此外,我们要确保总价格尽可能低。如果无法满足这些条件,输出 -1。
解题思路
- 分类菜品:首先,我们可以将所有的菜根据是否含有蘑菇进行分类。我们可以将含有蘑菇的菜和不含蘑菇的菜分别存储在两个列表中。
- 排序:对于每个类别的菜品,我们可以按价格从低到高排序,因为我们需要选出总价格最小的菜。
- 选择菜品:根据菜品的分类和价格排序,首先选择不含蘑菇的菜,直到选择了
k道菜或选择了m道含有蘑菇的菜。如果无法选择满足条件的菜品,返回-1。 - 边界情况:考虑到当菜品数量不足时,直接返回
-1。
详细步骤
- 将菜品分为两类:含蘑菇的菜和不含蘑菇的菜。
- 按照价格对这两类菜分别进行排序。
- 尝试从不含蘑菇的菜中选择最多
k道菜,剩下的可以从含蘑菇的菜中选择,且不超过m道。 - 计算最终选择的菜品总价格,返回最小的总价格。
代码实现
def min_cost(s, a, m, k):
# 分离含蘑菇和不含蘑菇的菜
mushroom_dishes = []
no_mushroom_dishes = []
for i in range(len(s)):
if s[i] == '1': # 含有蘑菇
mushroom_dishes.append(a[i])
else: # 不含蘑菇
no_mushroom_dishes.append(a[i])
# 对两类菜品按价格进行升序排序
mushroom_dishes.sort()
no_mushroom_dishes.sort()
# 如果选择k道菜品的数量超过了所有可选的菜品数量,则返回-1
if len(mushroom_dishes) + len(no_mushroom_dishes) < k:
return -1
# 尝试选择最多m个蘑菇菜
min_cost = float('inf')
# 选择x个含蘑菇的菜,其中0 <= x <= min(m, len(mushroom_dishes))
for x in range(min(m, len(mushroom_dishes)) + 1):
if k - x <= len(no_mushroom_dishes): # 剩余需要从无蘑菇菜中选择
# 选择x个蘑菇菜和k-x个不含蘑菇的菜
selected_cost = sum(mushroom_dishes[:x]) + sum(no_mushroom_dishes[:k - x])
min_cost = min(min_cost, selected_cost)
return min_cost if min_cost != float('inf') else -1
# 测试
s = "001"
a = [10, 20, 30]
m = 1
k = 2
print(min_cost(s, a, m, k)) # 输出:30
代码解释
- 分类菜品:我们遍历菜品的
s列表,判断是否含有蘑菇。如果是蘑菇菜,将其加入mushroom_dishes列表,否则加入no_mushroom_dishes列表。 - 排序:分别对两类菜品的价格进行升序排序,以便后续选择价格最小的菜品。
- 选择菜品:我们尝试从含蘑菇的菜品中选择
x道菜,其中x的范围是0到min(m, len(mushroom_dishes))。然后,我们选择剩余的k - x道不含蘑菇的菜品。计算总价格并更新最小价格。 - 返回结果:如果能够选择
k道菜且符合条件,返回最小价格;如果无法满足条件,则返回-1。
测试结果
对于输入:
s = "001"
a = [10, 20, 30]
m = 1
k = 2
程序输出:
30
复杂度分析
-
时间复杂度:
- 分类菜品时需要遍历
n道菜,时间复杂度为 O(n)。 - 对两类菜品分别排序,时间复杂度为 O(n log n)。
- 遍历所有可能的含蘑菇菜品选择数量时,最多有
m + 1种选择方式,每种方式计算总价格需要 O(k) 的时间。因此选择的时间复杂度为 O(m * k)。
综合起来,时间复杂度为 O(n log n + m * k)。
- 分类菜品时需要遍历
-
空间复杂度:O(n),用于存储两类菜品的价格。
这个算法应该能在大多数情况下高效运行,尤其是当菜品数量不非常庞大时。