问题描述
小S在码头租用货船,有 Q 种不同类型的货船可供选择。每种货船有固定的数量 m[i]、租赁成本 v[i] 和最大载货量 w[i]。小S希望在预算 V 元内,租用能够承载最大总货物的货船组合。每种货船的具体信息包括数量、租赁价格和载货量。小S需要你帮忙计算在给定预算下,她能租用的货船的最大总载货量是多少。
Q: 货船的种类数量。V: 李华可用的总预算(单位:元)。ships: 一个列表,其中每个元素是一个元组[m[i], v[i], w[i]],分别表示第i种货船的数量、租赁价格和每艘货船的最大载货量。
测试样例
样例1:
输入:
Q = 2,V = 10,ships = [[2, 3, 2], [3, 2, 10]]
输出:32
样例2:
输入:
Q = 3,V = 50,ships = [[5, 10, 20], [2, 20, 30], [3, 15, 25]]
输出:100
样例3:
输入:
Q = 1,V = 100,ships = [[10, 5, 50]]
输出:500
样例4:
输入:
Q = 4,V = 100,ships = [[1, 100, 200], [2, 50, 100], [3, 33, 66], [4, 25, 50]]
输出:200
样例5:
输入:
Q = 2,V = 300,ships = [[100, 1, 1], [50, 5, 10]]
输出:550
分析:
-
理解问题:我们需要在预算
V元内,选择能够承载最大总货物的货船组合。每种货船有数量限制、租赁成本和载货量。 -
数据结构选择:我们可以使用动态规划来解决这个问题。定义一个二维数组
dp,其中dp[i][j]表示在前i种货船中,使用不超过j元的预算所能获得的最大载货量。 -
算法步骤:
- 初始化
dp数组,dp[0][j]表示没有选择任何货船时的最大载货量,显然为 0。 - 对于每种货船,考虑选择不同数量的该种货船,更新
dp数组。 - 最终
dp[Q][V]就是我们所求的最大载货量。
- 初始化
代码:
def solution(Q, V, ships): # 初始化 dp 数组,dp[i][j] 表示在前 i 种货船中,使用不超过 j 元的预算所能获得的最大载货量 dp = [[0] * (V + 1) for _ in range(Q + 1)]
# 遍历每种货船
for i in range(1, Q + 1):
m, v, w = ships[i - 1] # 当前货船的数量、租赁价格和载货量
# 遍历预算
for j in range(V + 1):
# 考虑选择不同数量的当前货船
for k in range(min(m, j // v) + 1):
# 更新 dp 数组
dp[i][j] = max(dp[i][j], dp[i - 1][j - k * v] + k * w)
# 返回最大载货量
return dp[Q][V]
if name == "main": # 测试样例 ships = [[2, 3, 2], [3, 2, 10]] ships2 = [[30, 141, 47], [9, 258, 12], [81, 149, 13], [91, 236, 6], [27, 163, 74], [34, 13, 58], [61, 162, 1], [80, 238, 29], [36, 264, 28], [36, 250, 2], [70, 214, 31], [39, 116, 39], [83, 287, 4], [61, 269, 94], [23, 187, 46], [78, 33, 29], [46, 151, 2], [71, 249, 1], [67, 76, 85], [72, 239, 17], [61, 256, 49], [48, 216, 73], [39, 49, 74]] print(solution(2, 10, ships) == 32) print(solution(23, 400, ships2) == 1740)
代码解释
-
函数定义:
solution(Q, V, ships):这是一个函数,接受三个参数:货船种类数量Q,总预算V,以及一个包含每种货船信息的列表ships。
-
初始化
dp数组:dp = [[0] * (V + 1) for _ in range(Q + 1)]:创建一个二维数组dp,其中dp[i][j]表示在前i种货船中,使用不超过j元的预算所能获得的最大载货量。初始值为0。
-
遍历每种货船:
for i in range(1, Q + 1)::遍历每种货船,从第1种到第Q种。m, v, w = ships[i - 1]:获取当前货船的数量m、租赁价格v和载货量w。
-
遍历预算:
for j in range(V + 1)::遍历预算,从0到V。for k in range(min(m, j // v) + 1)::考虑选择不同数量的当前货船,k的范围是从0到min(m, j // v),即最多选择m艘或预算允许的最大数量。
-
更新
dp数组:dp[i][j] = max(dp[i][j], dp[i - 1][j - k * v] + k * w):更新dp[i][j],表示在前i种货船中,使用不超过j元的预算所能获得的最大载货量。这里使用了动态规划的思想,通过比较当前值和选择k艘当前货船后的值来更新。
-
返回结果:
return dp[Q][V]:返回在前Q种货船中,使用不超过V元的预算所能获得的最大载货量。
-
测试样例:
if __name__ == "__main__"::主程序入口。print(solution(2, 10, ships) == 32):测试第一个样例,预期输出为32。print(solution(23, 400, ships2) == 1740):测试第二个样例,预期输出为1740。
优化建议
-
空间优化:
- 当前的
dp数组是一个二维数组,占用了(Q+1) * (V+1)的空间。可以考虑使用一维数组来优化空间复杂度,因为每次更新只依赖于前一行的状态。
- 当前的
-
预算从大到小更新:
- 在更新
dp数组时,可以从大到小遍历预算,这样可以避免在更新dp数组时覆盖之前的状态,确保每次更新都是基于前一行的状态。
- 在更新
-
减少嵌套层数:
- 虽然仍然有三层循环,但通过优化预算的遍历顺序,减少了不必要的计算。
豆包 AI 刷题的优势
首先,豆包 AI 刷题的最大优势在于个性化学习。该工具通过大数据分析和机器学习技术,能够根据用户的学习习惯、知识掌握情况和薄弱环节,提供量身定制的练习题。这种个性化的学习方案,使得每个学生都能在自己的节奏下进行学习,从而提高了学习效果。
其次,豆包 AI 刷题具备实时反馈的功能。学生在完成练习后,系统会迅速对其答案进行评估,指出错误并给出正确的解题思路。这一过程不仅使学生能够及时纠正错误,还能加深对知识点的理解。例如,某名学生在数学练习中反复出现同一类型的问题,通过系统的反馈,他识别出了自己的误区,并在接下来的学习中得到了显著改善。
再次,豆包 AI 刷题涵盖了丰富的题库和多样的练习形式。这不仅包括选择题、填空题,还包括应用题和解答题,旨在培养学生的综合素养。针对某一特定学科或知识点,学生可以选择不同难度的题目进行训练,从而做到有针对性地提高。
最后,豆包 AI 刷题支持多设备同步学习,使得学生能够随时随地进行学习。无论是在课堂上、课外还是在家中,只需连接网络,学生便可轻松进行刷题,提高了学习的灵活性和便利性。
总结:
在当今这个充满竞争的学习环境中,掌握高效的学习方法对于提升个人能力至关重要。为了在这个快速变化的时代中保持竞争力,我们需要不断地学习新知识、新技能。豆包MarsCode AI的刷题功能为我们提供了一个强大的学习工具,可以帮助我们更有效地制定学习计划和提升学习效率。
时间管理是学习过程中的一个重要方面。我们可以结合时间管理工具,如番茄工作法应用,设定学习目标与时间段,合理安排AI刷题与其他学习活动的时间。同时,利用AI提供的实时反馈,我们可以及时调整学习策略,保持对知识的持续兴趣。
最后,我们需要定期回顾和自我评价。将AI刷题与复习计划结合,通过设置复习提醒和使用间隔重复技术,确保在适当的时间对知识进行再学习。自我评价可以帮助我们分析学习效果,识别需要改进的领域,从而不断优化我们的学习计划。
通过这样的学习计划和工具的运用,我们可以更有效地提升学习效率,实现个人能力的提升。在这个过程中,我们不仅能够学习到新知识,还能够培养出更好的学习习惯和时间管理能力,这些都是在当今竞争激烈的环境中取得成功的关键因素。