小C来到了一家饭馆,这里共有 n 道菜,第 i 道菜的价格为 ai。其中一些菜中含有蘑菇,si 代表第 i 道菜是否含有蘑菇。如果 s_i = '1',那么第 i 道菜含有蘑菇,否则没有。
小C希望点 k 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 m 道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出 -1。
首先,我们需要明确目标:在点 k 道菜的情况下,选择总价格最小的菜品组合,同时确保含有蘑菇的菜品数量不超过 m 道。为了有效地找到最优解,需要对菜品进行分类和排序,以便于后续的选择和计算。
将所有菜品按照是否含有蘑菇分为两类:
- 不含蘑菇的菜品(A类) :这些菜品对小C来说没有额外的限制,可以尽可能多地选择。
- 含有蘑菇的菜品(B类) :由于小C不喜欢蘑菇,选择这些菜品的数量受到 m 的限制。
为了在满足条件的情况下使总价格最小,我们需要优先选择价格低的菜品。因此,对A类和B类菜品分别按照价格从低到高排序。这样,在后续选择菜品时,可以直接从价格最低的菜品开始考虑。
接下来,需要确定在满足条件的前提下,含有蘑菇的菜品(B类)可以选择的数量范围。
- 最少需要选择的蘑菇菜数量:如果不含蘑菇的菜品数量不足 k 道,那么必须从含有蘑菇的菜品中选择一些菜品,以凑够 k 道菜。因此,最少需要选择的蘑菇菜数量为:
- 最多可以选择的蘑菇菜数量:不能超过题目限制的 m 道,也不能超过B类菜品的总数。因此,最多可以选择的蘑菇菜数量为:
在确定了蘑菇菜的选择范围后,需要遍历所有可能的蘑菇菜数量组合。对于每个可能的蘑菇菜数量 mushroom_count,对应的不含蘑菇菜品数量为:
需要确保 on_mushroom_count≤len(A),即不含蘑菇的菜品数量足够。
对于每一种可能的蘑菇菜数量组合,计算总价格:
- 从A类菜品中选择价格最低的 non_mushroom_count 道菜。
- 从B类菜品中选择价格最低的 mushroom_count 道菜。
总价格为上述菜品价格之和。在所有可能的组合中,记录并更新最小的总价格。需要注意的是,如果在遍历所有组合后,仍未找到满足条件的菜品组合,则最终输出 -1。
def solution(s: str, a: list, m: int, k: int) -> int:
A = [] # Dishes without mushrooms
B = [] # Dishes with mushrooms
n = len(a)
for i in range(n):
if s[i] == '0':
A.append(a[i])
else:
B.append(a[i])
A.sort()
B.sort()
total_dishes = len(A) + len(B)
if total_dishes < k:
return -1
min_total_cost = float('inf')
max_pick_b = min(k, m, len(B))
min_pick_b = max(0, k - len(A))
prefix_sum_A = [0]
for price in A:
prefix_sum_A.append(prefix_sum_A[-1] + price)
prefix_sum_B = [0]
for price in B:
prefix_sum_B.append(prefix_sum_B[-1] + price)
for pick_b in range(min_pick_b, max_pick_b + 1):
pick_a = k - pick_b
if pick_a <= len(A):
total_cost = prefix_sum_A[pick_a] + prefix_sum_B[pick_b]
if total_cost < min_total_cost:
min_total_cost = total_cost
if min_total_cost == float('inf'):
return -1
else:
return min_total_cost