问题描述
一个旅行者外出旅行时需要将 n 件物品装入背包,背包的总容量为 m。每个物品都有一个重量和一个价值。你需要根据这些物品的重量和价值,决定如何选择物品放入背包,使得在不超过总容量的情况下,背包中物品的总价值最大。
给定两个整数数组 weights 和 values,其中 weights[i] 表示第 i 个物品的重量,values[i] 表示第 i 个物品的价值。你需要输出在满足背包总容量为 m 的情况下,背包中物品的最大总价值。
问题分析
我们可以使用动态规划来解决这个问题。动态规划是一种通过将复杂问题分解为更小的子问题来解决问题的有效方法(类似递归思想)。比如求最优结构问题,最优解可以由其子问题的最优解构成。例如,求解最短路径、最大价值等问题。或者一个问题可以被分解成多个子问题,这些子问题在解决过程中会重复出现。动态规划通过缓存这些子问题的结果来避免重复计算,从而提高效率。
解题思路
定义状态:
dp[i][j]表示使用前i件物品,背包容量为j时的最大价值。
状态转移:
- 当考虑第
i件物品时,如果选择放入背包,则需要计算当前物品的价值加上剩余容量的最优解,即:dp[i][j] = dp[i - 1][j - weights[i - 1]] + values[i - 1]。 - 如果不放入物品,则继承之前的最优解:
dp[i][j] = dp[i - 1][j]。
初始化:在 dp[0][j] 中,表示没有物品可放时的最大价值都是 0。在 dp[i][0] 中,表示背包容量为 0 时的最大价值也是 0。
计算顺序:通过两层循环,从 1 到 n 和从 0 到 m 来填充 dp 数组。
返回结果:最终的最大价值存储在 dp[n][m] 中。
python实现
# 创建一个 (n + 1) 行 (m + 1) 列的二维数组 dp,用于存储每个状态的最大价值
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
# 遍历每一个物品
for i in range(1, n + 1):
# 遍历背包的每一个可能容量 j
for j in range(m + 1):
# 如果当前物品的重量小于等于背包的容量 j
if weights[i - 1] <= j:
# 选择放入当前物品,计算放入和不放入的最大价值
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])
# dp[i-1][j] 是不放入当前物品的情况
# dp[i-1][j - weights[i - 1]] + values[i - 1] 是放入当前物品的情况
else:
# 如果当前物品的重量大于背包的容量 j,则不能放入
dp[i][j] = dp[i - 1][j] # 直接继承不放入当前物品的情况
# 返回使用所有物品,背包容量为 m 时的最大价值
return dp[n][m]
豆包MarsCode AI对代码的优化
在编程的旅程中,我们常常面临各种挑战。完成一段代码的编写并通过编译,似乎就意味着成功了。然而,真正的挑战往往在于优化。这不仅是提高代码性能的关键,也是我们作为开发者需要掌握的重要技能之一。在这方面,MarsCode AI 显示出了卓越的能力。
在解答0-1背包问题时,初步完成的代码虽然顺利编译,但在性能和可读性上还有提升的空间。当我点击了MarsCode AI的代码优化功能,令人惊喜的是,它不仅帮助我简化了代码逻辑,还显著提高了运行效率。
它识别出了潜在的冗余计算,并提出了精简建议。优化后的代码更为简洁,逻辑清晰,执行速度也得到了提升。优化代码不仅是为了更高的性能,更是为了构建更健壮、可维护的程序。下次编写代码时,我将更加注重优化这一步骤,并期待在 MarsCode AI 的辅助下,创造出更优秀的作品!✨
以下是豆包MarsCode AI提供的代码,是不是很简洁!!哈哈,自愧不如!
# 初始化dp数组
dp = [0] * (m + 1)
# 状态转移
for i in range(n):
for j in range(m, weights[i] - 1, -1):
dp[j] = max(dp[j], dp[j - weights[i]] + values[i])
# 返回结果
return dp[m]
心得与体会
动态规划是一种强大的算法设计思想,主要用于解决具有最优子结构和重叠子问题的复杂问题。在实现动态规划时,我们不仅需要清晰地定义状态和状态转移方程,还需要合理地选择数据结构以优化存储和计算。通过动态规划,我们可以将问题规模缩小,从而在许多情况下显著提高解决问题的效率。例如,0-1背包问题便是经典的动态规划案例,通过合理的状态定义和转移,我们能够在保证不超出背包容量的情况下,最大化物品的总价值。
在刷题的过程中,豆包MarsCode AI不仅能够帮助我们检测代码错误,还能提供高效的优化建议,提升代码的执行效率和可读性。通过分析初步实现的代码,MarsCode AI 能够指出冗余计算和潜在的性能瓶颈,从而建议更优的解决方案。此外,还提供清晰的解释,使得用户能够深入理解优化的原因和方法。这种智能辅助,不仅提高了我的代码质量,也培养了我们在解决问题时的思维能力。通过 MarsCode AI 的支持,我们可以在刷题的学习与应用中走得更远,变得更加高效!✨