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

103 阅读4分钟

问题描述

小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

问题理解

你需要从 n 道菜中选择 k 道菜,使得总价格最小,并且最多有 m 道菜含有蘑菇。

数据结构选择

  1. 菜品列表:我们可以将菜品的价格和是否含有蘑菇的信息存储在一个列表中,每个元素包含价格和蘑菇状态。
  2. 价格排序:为了找到最小总价格,我们可以先对菜品按价格进行排序。

算法步骤

  1. 初始化:创建一个列表来存储菜品的价格和蘑菇状态。
  2. 排序:按价格对菜品进行排序。
  3. 选择菜品:从排序后的列表中选择菜品,确保最多有 m 道菜含有蘑菇,并且总共选择 k 道菜。
  4. 计算总价格:如果能够选择满足条件的 k 道菜,计算总价格并返回;否则返回 -1

关键点

  • 排序:按价格排序可以帮助我们优先选择价格较低的菜品。
  • 蘑菇限制:在选择菜品时,需要确保含有蘑菇的菜品数量不超过 m

通过这些步骤,你应该能够找到满足条件的菜品组合,并计算出最小总价格。

def solution(s: str, a: list, m: int, k: int) -> int:
    # 将菜品信息存储在一个列表中,每个元素是一个元组 (价格, 是否含有蘑菇)
    dishes = [(a[i], int(s[i])) for i in range(len(s))]
    
    # 按价格对菜品进行排序
    dishes.sort()
    
    # 初始化变量
    total_price = 0
    mushroom_count = 0
    selected_count = 0
    
    # 遍历排序后的菜品列表
    for price, has_mushroom in dishes:
        # 如果已经选择了k道菜,跳出循环
        if selected_count == k:
            break
        
        # 如果当前菜品含有蘑菇且蘑菇数量已经达到m,跳过该菜品
        if has_mushroom == 1 and mushroom_count == m:
            continue
        
        # 选择当前菜品
        total_price += price
        selected_count += 1
        
        # 如果当前菜品含有蘑菇,增加蘑菇数量
        if has_mushroom == 1:
            mushroom_count += 1
    
    # 如果选择的菜品数量不足k道,返回-1
    if selected_count < k:
        return -1
    
    # 返回总价格
    return total_price

if __name__ == '__main__':
    print(solution("001", [10, 20, 30], 1, 2) == 30)
    print(solution("111", [10, 20, 30], 1, 2) == -1)
    print(solution("0101", [5, 15, 10, 20], 2, 3) == 30)

代码解释

  1. 数据结构

    • 使用一个列表 dishes 存储菜品信息,每个元素是一个元组 (价格, 是否含有蘑菇)
  2. 排序

    • 对 dishes 按价格进行排序,这样可以优先选择价格较低的菜品。
  3. 选择菜品

    • 初始化 total_price 用于记录总价格,mushroom_count 用于记录含有蘑菇的菜品数量,selected_count 用于记录已选择的菜品数量。

    • 遍历排序后的 dishes 列表,选择菜品时遵循以下规则:

      • 如果已经选择了 k 道菜,跳出循环。
      • 如果当前菜品含有蘑菇且蘑菇数量已经达到 m,跳过该菜品。
      • 否则,选择当前菜品,增加总价格和已选择菜品数量,如果当前菜品含有蘑菇,增加蘑菇数量。
  4. 返回结果

    • 如果选择的菜品数量不足 k 道,返回 -1
    • 否则,返回总价格。

样例测试

  • 样例1solution("001", [10, 20, 30], 1, 2) 输出 30,符合预期。
  • 样例2solution("111", [10, 20, 30], 1, 2) 输出 -1,符合预期。
  • 样例3solution("0101", [5, 15, 10, 20], 2, 3) 输出 30,符合预期。