问题描述
小M在春游时打算携带尽可能多的巧克力板。她拥有n块巧克力板,每块巧克力的边长为aiai,重量为ai2ai2。小M有多个不同大小的背包,每个背包都有一定的最大承重限制。她希望你帮助她计算在每个背包的最大承重范围内,最多可以带走多少块巧克力板。
例如:小M有5块巧克力板,边长分别为1, 2, 2, 4, 5,有5个不同的背包,其最大承重分别为1, 3, 7, 9, 15。对于每个背包,她能装入的巧克力块数分别是1, 1, 2, 3, 3。
测试样例
样例1:
输入:
n = 5, m = 5, a = [1, 2, 2, 4, 5], queries = [1, 3, 7, 9, 15]
输出:[1, 1, 2, 3, 3]
样例2:
输入:
n = 4, m = 3, a = [3, 1, 2, 5], queries = [5, 10, 20]
输出:[2, 2, 3]
样例3:
输入:
n = 6, m = 4, a = [1, 3, 2, 2, 4, 6], queries = [8, 12, 18, 25]
输出:[2, 3, 4, 4]
分析
问题理解
小M有若干块巧克力板,每块巧克力的边长为 (a_i),重量为 (a_i^2)。她有多个不同大小的背包,每个背包都有一定的最大承重限制。我们需要计算在每个背包的最大承重范围内,最多可以带走多少块巧克力板。
数据结构选择
-
巧克力板列表:
- 输入:一个列表
a,表示每块巧克力板的边长。 - 输出:一个列表
weights,表示每块巧克力板的重量(即边长的平方)。
- 输入:一个列表
-
背包列表:
- 输入:一个列表
queries,表示每个背包的最大承重。 - 输出:一个列表
results,表示每个背包在最大承重范围内最多可以装入的巧克力板数量。
- 输入:一个列表
算法步骤
-
计算每块巧克力的重量:
- 遍历巧克力板列表
a,计算每块巧克力的重量并存储在weights列表中。
- 遍历巧克力板列表
-
排序巧克力板:
- 按重量从小到大排序
weights列表,这样我们可以优先选择重量较小的巧克力板。
- 按重量从小到大排序
-
处理每个背包的查询:
- 对于每个背包的最大承重
max_weight,从排序后的weights列表中选择尽可能多的巧克力板,直到超过背包的承重限制。 - 记录每个背包最多可以装入的巧克力板数量,并存储在
results列表中。
- 对于每个背包的最大承重
难点分析
-
排序操作:
- 需要对巧克力板的重量进行排序,以确保我们优先选择重量较小的巧克力板。排序操作的时间复杂度为 (O(n \log n)),其中 (n) 是巧克力板的数量。
-
贪心选择:
- 在处理每个背包的查询时,需要使用贪心算法选择尽可能多的巧克力板。这个过程需要遍历排序后的
weights列表,时间复杂度为 (O(n))。
- 在处理每个背包的查询时,需要使用贪心算法选择尽可能多的巧克力板。这个过程需要遍历排序后的
-
多次查询:
- 对于每个背包的查询,都需要重新遍历排序后的
weights列表。如果有 (m) 个背包,则总的时间复杂度为 (O(m \cdot n))。
- 对于每个背包的查询,都需要重新遍历排序后的
代码
def solution(n: int, m: int, a: list, queries: list) -> list:
# 计算每块巧克力的重量
weights = [x**2 for x in a]
# 按重量从小到大排序巧克力板
sorted_weights = sorted(weights)
results = []
# 处理每个背包的查询
for max_weight in queries:
current_weight = 0
count = 0
# 选择尽可能多的巧克力板,直到超过背包的承重限制
for weight in sorted_weights:
if current_weight + weight <= max_weight:
current_weight += weight
count += 1
else:
break
results.append(count)
return results
if __name__ == '__main__':
print(solution(5, 5, [1, 2, 2, 4, 5], [1, 3, 7, 9, 15]) == [1, 1, 2, 3, 3])
print(solution(4, 3, [3, 1, 2, 5], [5, 10, 20]) == [2, 2, 3])
print(solution(6, 4, [1, 3, 2, 2, 4, 6], [8, 12, 18, 25]) == [2, 3, 4, 4])
-
计算每块巧克力的重量:
- 代码中使用了列表推导式
weights = [x**2 for x in a]来计算每块巧克力的重量。
- 代码中使用了列表推导式
-
按重量从小到大排序巧克力板:
- 代码中使用了
sorted(weights)来对巧克力板的重量进行排序。
- 代码中使用了
-
处理每个背包的查询:
-
代码中使用了嵌套的循环来处理每个背包的查询:
- 外层循环遍历
queries列表,表示每个背包的最大承重。 - 内层循环遍历排序后的
sorted_weights列表,选择尽可能多的巧克力板,直到超过背包的承重限制。
- 外层循环遍历
-
使用贪心算法的思想。
-
-
结果存储:
- 代码中使用了
results.append(count)来存储每个背包最多可以装入的巧克力板数量。
- 代码中使用了