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

94 阅读3分钟

问题描述

小C来到了一家饭馆,这里共有 n 道菜:

  • i 道菜的价格为 a[i]
  • 如果第 i 道菜含有蘑菇,则 s[i] = '1',否则 s[i] = '0'

小C希望点 k 道菜,并且:

  1. 总价格尽可能低
  2. 所点菜中最多只能有 m 道菜含有蘑菇。

输出满足条件的最小总价格,若无法满足条件则输出 -1

示例分析

样例1

输入:
s = "001", a = [10, 20, 30], m = 1, k = 2
分析:

  • 菜品信息:
    • 菜1:无蘑菇,价格10;
    • 菜2:无蘑菇,价格20;
    • 菜3:有蘑菇,价格30。
  • 需求:选2道菜,总价格最小,且最多1道菜有蘑菇。

策略:

  1. 按价格升序选择。
  2. 优先选择无蘑菇菜品(菜1和菜2)。

结果:选菜1和菜2,总价格为 10 + 20 = 30

输出:30


样例2

输入:
s = "111", a = [10, 20, 30], m = 1, k = 2
分析:

  • 所有菜都含有蘑菇,无法满足“最多1道菜有蘑菇”的条件。

输出:-1


样例3

输入:
s = "0101", a = [5, 15, 10, 20], m = 2, k = 3
分析:

  • 菜品信息:
    • 菜1:无蘑菇,价格5;
    • 菜2:有蘑菇,价格15;
    • 菜3:无蘑菇,价格10;
    • 菜4:有蘑菇,价格20。
  • 需求:选3道菜,总价格最小,且最多2道菜有蘑菇。

策略:

  1. 按价格升序选择。
  2. 优先选择无蘑菇的菜(菜1、菜3),再选一个有蘑菇的菜(菜2)。

结果:选菜1、菜3、菜2,总价格为 5 + 10 + 15 = 30

输出:30


解决思路

  1. 数据整理:

    • 将每道菜的信息(是否含有蘑菇、价格)打包成元组:(s[i], a[i])
    • 按价格升序排序。
  2. 贪心策略:

    • 遍历排序后的菜品列表,逐个选择。
    • 优先选择无蘑菇的菜;如果无蘑菇的菜数量不足,再选择含有蘑菇的菜,但要满足蘑菇菜品限制。
  3. 边界处理:

    • 如果无法满足选够 k 道菜的条件,则返回 -1

代码实现

def solution(s: str, a: list, m: int, k: int) -> int:
    # 合并蘑菇信息和价格,并按价格排序
    dishes = [(s[i], a[i]) for i in range(len(a))]
    dishes.sort(key=lambda x: x[1])
    
    total_cost = 0  # 总价格
    selected_count = 0  # 已选菜品数量
    mushroom_count = 0  # 已选蘑菇菜品数量
    
    # 遍历排序后的菜品
    for dish in dishes:
        if selected_count < k:  # 如果未选够菜
            if dish[0] == '1':  # 是蘑菇菜
                if mushroom_count < m:  # 如果蘑菇菜品未超限
                    total_cost += dish[1]
                    selected_count += 1
                    mushroom_count += 1
            else:  # 无蘑菇菜
                total_cost += dish[1]
                selected_count += 1
    
    # 如果选不够 k 道菜,返回 -1
    if selected_count < k:
        return -1
    
    return total_cost
 if __name__ == '__main__':
    # 示例测试
    print(solution("001", [10, 20, 30], 1, 2) == 30)  # 样例1
    print(solution("111", [10, 20, 30], 1, 2) == -1)  # 样例2
    print(solution("0101", [5, 15, 10, 20], 2, 3) == 30)  # 样例3

    # 边界测试
    print(solution("0", [10], 0, 1) == 10)  # 仅有1道菜,无蘑菇
    print(solution("1", [10], 0, 1) == -1)  # 仅有1道菜,且含蘑菇但不允许
    print(solution("101", [10, 15, 20], 1, 3) == -1)  # 无法满足选够3道菜
    print(solution("000", [5, 10, 15], 1, 3) == 30)  # 全为无蘑菇菜

知识总结

  1. 贪心算法:
  • 此题采用贪心策略:按价格升序选择,优先选择无蘑菇的菜。
  1. 列表排序与遍历:****
  • list.sort(key=lambda x: x[1]) 可按特定字段排序,便于后续处理。
  1. 边界处理:****
  • 确保选够 k 道菜,否则直接返回 -1。

工具运用:

  1. 使用AI刷题工具生成不同解法(如动态规划、回溯),对比学习。

  2. 针对错题,利用AI自动分析测试用例和逻辑漏洞,提高效率。

通过系统化的刷题练习和工具结合,逐步掌握贪心算法的核心思路和应用场景。