AI刷题笔记 06
题目描述:饭馆菜品选择问题
小C来到了一家饭馆,这里共有n道菜,第i道菜的价格为a_i。其中一些菜中含有蘑菇,s_i代表第i道菜是否含有蘑菇。如果s_i='1'那么第i道菜含有蘑菇,否则没有。 小C希望点k 道菜,且希望总价格尽可能低。由于她不喜欢蘑菇,她希望所点的菜中最多只有m道菜含有蘑菇。小C想知道在满足条件的情况下能选出的最小总价格是多少。如果无法按照要求选择菜品,则输出-1。
样例01
输入:s=“001",a=[10,20,30],m=1,k=2 ;输出:30
解题核心思路
小C想选择 k 道菜,总价格尽可能低,并且满足以下条件:
- 至多有 m 道菜含有蘑菇。
- 菜的价格和是否含蘑菇分别用 a 和 s 数组表示,含蘑菇的菜用 s[i]=′1′ 表示。 如果无法满足条件,返回 -1。 则应在满足含有蘑菇的菜品数量小于等于 m 的前提下,寻找最低的菜品价格搭配。
题目分析
解题步骤
解题步骤如下:
- 分类记录菜品:
- 分别将含蘑菇和不含蘑菇的菜品放入不同的列表,方便后续操作。
- 对每个列表按价格排序:
- 先对不含蘑菇的菜进行排序。
- 再对含蘑菇的菜进行排序。
- 尝试组合最低价格的菜品:
- 从两类菜中选择 k 道,确保含蘑菇的菜数量不超过 m。
- 计算所有满足条件的组合的总价格,记录最小值。
- 返回结果:
- 如果无法满足条件,则返回 -1。
最终代码
def solution(s, a, m, k):
# 将含蘑菇和不含蘑菇的菜分开
with_mushroom = []
without_mushroom = []
for i in range(len(s)):
if s[i] == '1':
with_mushroom.append(a[i])
else:
without_mushroom.append(a[i])
# 按价格排序
with_mushroom.sort()
without_mushroom.sort()
# 如果菜的总数不足k,则直接返回 -1
if len(with_mushroom) + len(without_mushroom) < k:
return -1
# 计算所有可能的组合
min_price = float('inf')
for mushroom_count in range(min(m + 1, k + 1)): # 至多选 m 道含蘑菇的菜
non_mushroom_count = k - mushroom_count # 剩余的从不含蘑菇的菜中选择
# 检查是否满足蘑菇和非蘑菇菜的数量要求
if mushroom_count <= len(with_mushroom) and non_mushroom_count <= len(without_mushroom):
price = sum(with_mushroom[:mushroom_count]) + sum(without_mushroom[:non_mushroom_count])
min_price = min(min_price, price)
# 如果没有满足条件的组合,返回 -1,否则返回最小价格
return min_price if min_price != float('inf') else -1
代码解释
- 分类记录菜品:
- 将 s[i]=′1′ 的菜加入
with_mushroom。 - 其他菜加入
without_mushroom。
- 将 s[i]=′1′ 的菜加入
- 排序:
- 按价格从低到高排序,为了快速选择最低价格的菜。
- 尝试所有可能的组合:
- 用两层循环尝试蘑菇菜的数量,从 0 到 min(m,k)
- 剩余的菜必须从不含蘑菇的列表中选择,检查是否满足条件。
- 返回结果:
- 如果所有组合都不满足条件,返回 -1,否则返回最小总价格。
补充说明
改题目的整体思路为满足限定条件下的求和最小值问题,因此,首先明晰不符合条件导致输出结果为1的条件(即点菜数大于菜品总数,要求最多含蘑菇菜品数大于实际含蘑菇菜品数),而后,为寻求和最小值,将数据进行大小排列,寻找最小的价格数和,最终输出。