问题描述
小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
问题理解
-
输入:
s: 一个字符串,表示每道菜是否含有蘑菇。'1'表示含有蘑菇,'0'表示不含蘑菇。a: 一个列表,表示每道菜的价格。m: 一个整数,表示小C最多能接受的含有蘑菇的菜的数量。k: 一个整数,表示小C希望点的菜的总数量。
-
输出:
- 一个整数,表示在满足条件的情况下能选出的最小总价格。如果无法按照要求选择菜品,则输出
-1。
- 一个整数,表示在满足条件的情况下能选出的最小总价格。如果无法按照要求选择菜品,则输出
条件
- 小C希望点的菜中最多只有
m道菜含有蘑菇。 - 小C希望点的菜的总数量为
k。 - 小C希望总价格尽可能低。
数据结构选择
- 我们可以将每道菜的价格和是否含有蘑菇的信息组合在一起,形成一个元组列表。
- 然后对这个列表进行排序,优先选择价格低的菜。
算法步骤
-
组合信息: 将价格和是否含有蘑菇的信息组合成一个元组列表。
-
排序: 按照价格从小到大排序。
-
检查结果:
- 按照其他要求选择菜品,如果选择的菜品数量不足
k,则返回-1。 - 否则,返回所选菜品的最小总价格。
- 按照其他要求选择菜品,如果选择的菜品数量不足
通过这些步骤,我们可以确保在满足条件的情况下,选出的菜品总价格最小。
代码示例
def solution(s: str, a: list, m: int, k: int) -> int:
arr = list(zip(a, s))
arr.sort()
filtered = list()
for v, t in arr:
if t == "0":
filtered.append(v)
else:
if m:
filtered.append(v)
m -= 1
if len(filtered) < k:
return -1
return sum(filtered[:k])
时间复杂度
关键知识点
-
数据结构:
- 列表 (List) : 用于存储菜品的价格和是否含有蘑菇的信息。
- 元组 (Tuple) : 用于将价格和蘑菇信息组合在一起。
-
排序算法:
- 排序 (Sorting) : 使用
sort()方法对列表进行排序,以便优先选择价格低的菜品。
- 排序 (Sorting) : 使用
-
条件判断:
- 条件语句 (if-else) : 用于判断当前菜品是否含有蘑菇,并决定是否选择该菜品。
-
计数器:
- 计数器 (Counter) : 用于记录已经选择的含有蘑菇的菜的数量。
-
列表操作:
- 列表切片 (List Slicing) : 用于选择前
k道菜。 - 列表求和 (Sum) : 用于计算所选菜品的最小总价格。
- 列表切片 (List Slicing) : 用于选择前
详细解释
-
数据结构:
- 列表 (List) : 列表是Python中最常用的数据结构之一,可以存储多个元素。在这个问题中,我们使用列表来存储菜品的价格和是否含有蘑菇的信息。
- 元组 (Tuple) : 元组是不可变的序列,适合用于存储不需要修改的数据。在这个问题中,我们使用元组将价格和蘑菇信息组合在一起,形成一个元组列表。
-
排序算法:
- 排序 (Sorting) : 排序是计算机科学中的一个基本操作,用于将数据按照某种顺序排列。在这个问题中,我们使用
sort()方法对元组列表进行排序,排序的关键是价格,以便优先选择价格低的菜品。
- 排序 (Sorting) : 排序是计算机科学中的一个基本操作,用于将数据按照某种顺序排列。在这个问题中,我们使用
-
条件判断:
- 条件语句 (if-else) : 条件语句用于根据条件执行不同的代码块。在这个问题中,我们使用条件语句判断当前菜品是否含有蘑菇,并决定是否选择该菜品。
-
计数器:
- 计数器 (Counter) : 计数器用于记录某个事件发生的次数。在这个问题中,我们使用计数器记录已经选择的含有蘑菇的菜的数量。
-
列表操作:
- 列表切片 (List Slicing) : 列表切片用于从列表中选择一部分元素。在这个问题中,我们使用列表切片选择前
k道菜。 - 列表求和 (Sum) : 列表求和用于计算列表中所有元素的总和。在这个问题中,我们使用
sum()函数计算所选菜品的最小总价格。
- 列表切片 (List Slicing) : 列表切片用于从列表中选择一部分元素。在这个问题中,我们使用列表切片选择前