第三篇|饭馆菜品选择问题|豆包MarsCode AI技术刷题

7 阅读5分钟

一、问题描述

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

小C希望点 kk 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有 mm 道菜含有蘑菇。小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

二、代码展示

    def solution(s: str, a: list, m: int, k: int) -> int:
        n = len(s)
        if k > n:
            return -1

    min_price = float('inf')
    for i in range(2 ** n):
        selected_combination = bin(i)[2:].zfill(n)
        selected_count = selected_combination.count('1')
        mushroom_count = 0
        total_price = 0

        if selected_count == k:
            for j in range(n):
                if selected_combination[j] == '1':
                    total_price += a[j]
                    if s[j] == '1':
                        mushroom_count += 1

            if mushroom_count <= m:
                min_price = min(min_price, total_price)

    if min_price == float('inf'):
        return -1
    return min_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. 函数整体功能

 solution  函数的主要目的是根据给定的字符串  s 、整数列表  a 、整数  m  和  k ,从字符串  s  对应的元素组合中,找出满足特定条件(蘑菇数量限制和选取数量限制)的组合,并返回这些组合中总价格的最小值。如果没有满足条件的组合,则返回 -1。

2. 函数参数

  •  s :一个字符串,其每个字符可能对应着某种选择状态或条件判断依据。
  •  a :一个整数列表,列表中的每个元素应该是与  s  中对应位置元素相关联的价格值。
  •  m :一个整数,表示蘑菇数量的上限限制。
  •  k :一个整数,表示需要选取的元素数量。

3. 函数内部逻辑分析

初始化部分

  •  n = len(s) :获取字符串  s  的长度,用于后续循环遍历等操作的边界判断。
  •  min_price = float('inf') :初始化最小价格为正无穷大,以便后续在找到符合条件的组合时能更新为更小的值。

遍历所有可能的组合

  •  for i in range(2 ** n) :通过循环遍历从0到     的所有整数,这里的   表示字符串  s  所有可能的二进制选择组合数量(因为每个位置可以选或不选,相当于有   种状态,总共有  n  个位置)。
  •  selected_combination = bin(i)[2:].zfill(n) :
  • 首先使用  bin(i)  将整数  i  转换为二进制字符串形式。
  • 然后通过  [2:]  切片操作去掉二进制字符串开头的  0b  标识。
  • 最后使用  zfill(n)  方法将得到的二进制字符串填充为长度为  n  的字符串,确保每个可能的组合在长度上与字符串  s  相对应,这样就得到了一种具体的选择组合表示形式。
  •  selected_count = selected_combination.count('1') :计算当前选择组合  selected_combination  中字符  1  的数量,即当前组合中被选中的元素个数。

针对每个组合进行条件判断和价格计算

  • 当  selected_count == k  时,说明当前组合选中的元素数量恰好等于给定的  k ,此时进行以下操作:
  •  total_price = 0  和  mushroom_count = 0 :初始化当前组合的总价格和蘑菇数量统计值。
  • 内层循环  for j in range(n) :遍历字符串  s  和列表  a  的每个位置。
  • 当  selected_combination[j] == '1'  时:
  •  total_price += a[j] :将当前位置对应的价格  a[j]  添加到总价格  total_price  中,因为该位置在当前组合中被选中。
  • 若  s[j] == '1' :说明当前位置对应的元素可能是蘑菇相关的(根据具体情境推测),则将  mushroom_count  增加1。
  • 当  mushroom_count <= m  时:说明当前组合中蘑菇的数量满足不超过  m  的限制条件,此时更新最小价格  min_price :
  •  min_price = min(min_price, total_price) :将当前组合的总价格  total_price  与已记录的最小价格  min_price  进行比较,取较小值更新  min_price 。

最终结果返回

  • 如果  min_price == float('inf') :说明在所有遍历的组合中,没有找到满足条件(选中  k  个元素且蘑菇数量不超过  m )的组合,此时返回 -1。
  • 否则,返回  min_price ,即满足条件的组合中的最小总价格。

4. 主程序部分

在  if name == 'main':  语句块中,对  solution  函数进行了三次测试调用:

  •  print(solution("001", [10, 20, 30], 1, 2) == 30) :调用  solution  函数传入指定参数,预期返回值应该为30,然后通过比较返回值与30是否相等来验证函数在该输入情况下的正确性。

  •  print(solution("111", [10, 20, 30], 1, 2) == -1) :同样调用  solution  函数,由于字符串 "111" 中蘑菇数量很可能超过给定的  m = 1 (具体取决于函数内部对蘑菇的定义与判断),预期返回值为 -1,通过比较验证函数在此输入下的结果。

  •  print(solution("0101", [5, 15, 10, 20], 2, 3) == 30) :再次调用  solution  函数,传入相应参数,预期返回值为30,以此来进一步测试函数在不同输入参数组合下的准确性。

    通过这些测试用例,可以初步检验  solution  函数在不同场景下是否能正确计算并返回符合预期的结果。总体而言,这段代码围绕着对不同组合的遍历、条件判断以及价格计算来实现根据特定要求找出最优组合价格的功能。具体的实际应用场景需要根据代码所在的更大项目背景来进一步明确。