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

2 阅读3分钟

问题描述

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

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


解题思路

这道题目是一个典型的贪心算法问题,目标是尽可能选择低价格的菜品,同时满足约束条件。以下将详细分析题解逻辑并逐步讲解实现代码的思路。

1. 分类菜品

我们首先遍历所有菜品,根据它们是否含有蘑菇,将其划分成两组:

  • 不含蘑菇的菜,放入列表 no_mushroom
  • 含蘑菇的菜,放入列表 mushroom

这种分类能够帮助我们在后续处理中更加高效地做出选择。

2. 排序

为了尽可能降低总价格,我们需要优先选择价格最低的菜品。因此,将 mushroomno_mushroom 两个列表按照价格从低到高排序。

3. 贪心选择菜品

在选择菜品时,我们采取以下策略:

  • 每次从两个列表中选出价格最低的一道菜。
  • 如果当前选中的是含蘑菇的菜,则检查当前已经选了多少道含蘑菇的菜,确保不超过 m 的限制。
  • 如果当前选中的是不含蘑菇的菜,则直接选择。

通过这种贪心的方式,可以保证总价格是最低的。

4. 检查是否满足条件

在选择过程中,如果无法满足 k 道菜的要求,例如两个列表的菜品总数量不足 k,或者含蘑菇的菜超过限制 m,则直接返回 -1。


测试样例分析

样例:

输入:

  • s = "001"
  • a = [10, 20, 30]
  • m = 1
  • k = 2

分析:

  • 分为含蘑菇的菜:mushroom = [30],不含蘑菇的菜:no_mushroom = [10, 20]
  • 优先选择价格最低的两道不含蘑菇的菜:10 和 20。
  • 总价格:30。

输出: 30


样例2:

输入:

  • s = "111"
  • a = [10, 20, 30]
  • m = 1
  • k = 2

分析:

  • 全部菜都含有蘑菇:mushroom = [10, 20, 30]no_mushroom = []
  • m=1 限制只能选一道含蘑菇的菜,但 k=2 要求至少选两道,无法满足条件。

输出: -1


完整代码实现

python
复制代码
def solution(s: str, a: list, m: int, k: int) -> int:
    mushroom = []
    no_mushroom = []

    # 分类菜品
    for i in range(len(s)):
        if s[i] == "1":
            mushroom.append(a[i])
        else:
            no_mushroom.append(a[i])

    # 按价格升序排序
    mushroom.sort()
    no_mushroom.sort()

    # 贪心选择
    cost = 0
    p, q = 0, 0  # p为不含蘑菇菜指针,q为含蘑菇菜指针

    for i in range(k):
        if q < len(mushroom) and p < len(no_mushroom) and q < m:
            if no_mushroom[p] < mushroom[q]:
                cost += no_mushroom[p]
                p += 1
            else:
                cost += mushroom[q]
                q += 1
        elif p < len(no_mushroom):
            cost += no_mushroom[p]
            p += 1
        elif q < len(mushroom) and q < m:
            cost += mushroom[q]
            q += 1
        else:
            return -1  # 无法满足条件

    return cost

边界情况分析

  1. 没有蘑菇菜,且 k>len(no_mushroom):

    • 如果可选菜品总数不足,直接返回 -1。
  2. 所有菜品都含蘑菇,且 k>m:

    • m 限制无法满足 k 道菜的需求,返回 -1。

复杂度分析

  1. 时间复杂度:

    • 列表分类:O(n)。
    • 排序:O(nlog⁡n)。
    • 贪心选择:O(k)。
    • 总计:O(nlog⁡n)。
  2. 空间复杂度:

    • 两个额外列表存储分类结果:O(n)。