饭馆菜品选择 | 豆包MarsCode AI刷题

94 阅读3分钟

小C来到了一家饭馆,这里共有 n 道菜,第 i 道菜的价格为 ai。其中一些菜中含有蘑菇,si 代表第 i 道菜是否含有蘑菇。如果 s_i = '1',那么第 i 道菜含有蘑菇,否则没有。

小C希望点 k 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 m 道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出 -1。

首先,我们需要明确目标:在点 k 道菜的情况下,选择总价格最小的菜品组合,同时确保含有蘑菇的菜品数量不超过 m 道。为了有效地找到最优解,需要对菜品进行分类和排序,以便于后续的选择和计算。

将所有菜品按照是否含有蘑菇分为两类:

  1. 不含蘑菇的菜品(A类) :这些菜品对小C来说没有额外的限制,可以尽可能多地选择。
  2. 含有蘑菇的菜品(B类) :由于小C不喜欢蘑菇,选择这些菜品的数量受到 m 的限制。

为了在满足条件的情况下使总价格最小,我们需要优先选择价格低的菜品。因此,对A类和B类菜品分别按照价格从低到高排序。这样,在后续选择菜品时,可以直接从价格最低的菜品开始考虑。

接下来,需要确定在满足条件的前提下,含有蘑菇的菜品(B类)可以选择的数量范围。

  • 最少需要选择的蘑菇菜数量:如果不含蘑菇的菜品数量不足 k 道,那么必须从含有蘑菇的菜品中选择一些菜品,以凑够 k 道菜。因此,最少需要选择的蘑菇菜数量为:
min_mushroom=max(0,klen(A))min\_mushroom=max⁡(0,k−len(A))
  • 最多可以选择的蘑菇菜数量:不能超过题目限制的 m 道,也不能超过B类菜品的总数。因此,最多可以选择的蘑菇菜数量为:
max_mushroom=min(k,m,len(B))max\_mushroom=min⁡(k,m,len(B))

在确定了蘑菇菜的选择范围后,需要遍历所有可能的蘑菇菜数量组合。对于每个可能的蘑菇菜数量 mushroom_count,对应的不含蘑菇菜品数量为:

non_mushroom_count=kmushroom_countnon\_mushroom\_count=k−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