问题描述
小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
思路
目标:最低价购入 k道菜 并返回总价格,要求最多只有 m道有蘑菇的菜,无法满足则返回-1。
- 统计有蘑菇和无蘑菇菜的数量
- 将蘑菇的字符串转为整型数组
- 并统计有蘑菇和无蘑菇菜的数量
- 检查是否满足条件
- 当非蘑菇数小于
k-m,则无法满足只有m道蘑菇菜的条件
- 当非蘑菇数小于
- 创建菜品列表
- 数据结构采用列表 存储存储每道菜的价格和蘑菇状态
- 按价格排序,选择菜品
- 对菜品列表按价格进行排序
- 遍历排序后菜品列表,选择满足条件的菜品,直到选满
k道菜 - 若有蘑菇,当有蘑菇菜数小于m,则选;若无蘑菇,直接选
具体步骤
1. 统计蘑菇和非蘑菇菜的数量:
- 遍历
s字符串,统计含有蘑菇和不含蘑菇的菜的数量。
# 将字符串 s: str 转整型数组
int_s = [int(char) for char in list(s)]
count_no_mushroom = int_s.count(0)
count_with_mushroom = int_s.count(1)
相关知识点
整型数组名 = [int(char) for char in list(字符串名)]将字符串转为整型数组list(s)将字符串s转为一个字符列表int(char)将每个字符转换为整数for char in list(s)遍历字符列表中的每个字符- ★★
[int(char) for char in list(s)]用列表生成式,将每个字符转换为整型,并生成一个新的整型数组
列表名.count(元素)统计列表中某内容的数量
2. 检查是否可能满足条件:
- 如果非蘑菇菜的数量小于 k−m,则无法满足条件,直接返回
-1。if(count_no_mushroom < k - m): return -1
3. 创建菜品列表:
-
将每道菜的价格和蘑菇状态组合成一个元组列表。
dishes = [(a[i], int_s[i]) for i in range(len(s))]
4. 按价格排序:
-
使用
sort方法按价格对菜品列表进行排序。dishes.sort(key=lambda x: x[0])
相关知识点
lambda匿名函数lambda x: x[0]提取每个元组的第一个元素,(本题 即价格)key=___以___作为键
列表名.sort()列表排序dishes.sort(key=lambda x: x[0])对dishes列表中的元素 按价格 进行升序排序,提取每个元素的第一个元素(此为 价格)作为排序的键
5. 选择菜品:
-
遍历排序后的菜品列表,选择满足条件的菜品,直到选满 k 道菜。
- 如果某道菜含有蘑菇且当前已选择的蘑菇菜数量小于 m,则选择该菜。
- 如果某道菜不含蘑菇,则直接选择该菜。
# 初始化变量 total_price = 0 selected_mushroom = 0 selected_count = 0 # 选择菜品 for price, has_mushroom in dishes: # 有蘑菇,且蘑菇菜的数量不超过m if has_mushroom == 1 and selected_mushroom < m: total_price += price selected_mushroom += 1 selected_count += 1 # 没有蘑菇的情况 elif has_mushroom == 0: total_price += price selected_count += 1 # 如果已选择k道菜,则停止 if selected_count == k: break
6. 返回结果:
- 如果无法选满 k 道菜,返回
-1。 - 否则,返回总价格。
知识点整理
-
字符串处理:
-
字符串转换:将字符串
s转换为整型数组int_str。int_str = [int(char) for char in list(s)] -
统计字符出现次数:使用
count方法统计0的出现次数。count_no_mushroom = int_str.count(0)
-
-
列表操作:
-
列表生成:使用列表生成式创建包含每道菜价格和蘑菇状态的元组列表。
dishes = [(a[i], int_str[i]) for i in range(len(s))] -
列表排序:使用
sort方法按价格对列表进行排序。dishes.sort(key=lambda x: x[0])
-
-
贪心算法:
- 核心思想:在每一步选择中,都选择当前最优的选项,以期望最终结果是最优的。
- 应用场景:在本题中,我们希望在满足条件的情况下选择总价格最小的菜品。通过按价格排序,我们可以优先选择价格最低的菜品,从而逐步构建最优解。
-
遍历与选择:
- 核心思想:通过遍历数据集,选择满足条件的元素。
- 应用场景:在本题中,我们遍历排序后的菜品列表,选择满足条件的菜品,直到选满
k道菜。
python方面
-
lambda x: x[0]:匿名函数lambda是 Python 中的匿名函数(即没有名字的函数)。- 语法:
lambda x: x[0]定义了一个匿名函数,它接受一个参数x(表示列表中的每个元组),并返回x的第一个元素x[0]。 - ---->
lambda 参数: 返回元素
-
列表
-
字符串
s转换为列表:list(s) -
列表生成式:
[expression for item in iterable]-
参数:
expression表达式,item是从iterable中取出的每个元素,iterable可迭代对象(如列表、元组、字符串等) -
例子:创建包含多个元素的列表
dishes = [(a[i], int_list[i]) for i in range(len(s))]
-
-
列表计数
count方法:list.count(element)参数:
list列表名称,element要计数的对象,即计算列表list中含有多少个element -
列表排序
sort方法:list.sort(key=None, reverse=False)- 其中,
key参数是一个函数,用于从每个列表元素中提取一个用于排序的键;reverse参数用于指定排序顺序,默认为False(升序),如果设置为True,则为降序。 - 例子:
dishes.sort(key=lambda x: x[0])
- 其中,
-
完整代码
from re import S
def solution(s: str, a: list, m: int, k: int) -> int:
# 将字符串转整型数组
int_s = [int(char) for char in list(s)]
# 统计蘑菇和非蘑菇菜的数量
count_no_mushroom = int_s.count(0)
count_with_mushroom = int_s.count(1)
# 应该有 k-m 道无蘑菇的,才可能满足条件---> 如果非蘑菇菜的数量小于 k-m,则无法满足条件
if(count_no_mushroom < k - m):
return -1
# 创建列表,包含每道菜的价格和是否含有蘑菇的位置
dishes = [(a[i], int_s[i]) for i in range(len(s))]
# 按价格排序
dishes.sort(key=lambda x: x[0])
# 初始化变量
total_price = 0
selected_mushroom = 0
selected_count = 0
# 选择菜品
for price, has_mushroom in dishes:
# 有蘑菇,且蘑菇菜的数量不超过m
if has_mushroom == 1 and selected_mushroom < m:
total_price += price
selected_mushroom += 1
selected_count += 1
# 没有蘑菇的情况
elif has_mushroom == 0:
total_price += price
selected_count += 1
# 如果已选择k道菜,则停止
if selected_count == k:
break
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)
感受
豆包ai帮大忙,有思路但对python语法不熟悉,可以直接问他,具体问题具体分析,可以快速解决问题。好样的!!会ai提示词真的很重要,节省不少时间。语法知识蹭蹭蹭上升,实践中学习~~