问题描述
一个旅行者外出旅行时需要将 n 件物品装入背包,背包的总容量为 m。每个物品都有一个重量和一个价值。你需要根据这些物品的重量和价值,决定如何选择物品放入背包,使得在不超过总容量的情况下,背包中物品的总价值最大。
给定两个整数数组 weights 和 values,其中 weights[i] 表示第 i 个物品的重量,values[i] 表示第 i 个物品的价值。你需要输出在满足背包总容量为 m 的情况下,背包中物品的最大总价值。
题目解析:0/1背包问题
题目理解
一个旅行者需要在有限的背包容量 m 下,挑选 n 件物品,目的是使背包中物品的总价值最大化。这里的关键是“0/1选择”,即每件物品只能选择放入或不放入背包。
难点解析
- 约束条件:背包的总重量不能超过 m 。
- 状态选择:对于每件物品,有两种选择:放入背包或不放入背包,如何权衡是问题的核心。
代码解析:思路与实现
为解决这一问题,我们采用动态规划方法。核心思路是通过状态转移方程求解每个阶段的最优解。
1. 动态规划状态设计
定义一个二维数组 dp[i][j] ,其中:
- i 表示前 i 件物品;
- j 表示背包的容量;
- dp[i][j] 表示在容量 j 下选择前 i 件物品的最大价值。
2. 状态转移方程
- 如果当前物品的重量 weights[i - 1] > j ,无法放入背包,直接继承上一状态:
- 如果可以放入,则比较放入和不放入两种情况的价值,取最大值:
3. 代码实现
以下是代码实现:
public class Main {
public static int solution(int n, int[] weights, int[] values, int m) {
// 创建二维数组 dp
int[][] dp = new int[n + 1][m + 1];
// 动态规划求解
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
if (weights[i - 1] > j) {
// 当前物品重量超过容量
dp[i][j] = dp[i - 1][j];
} else {
// 比较放入和不放入两种情况
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]);
}
}
}
// 返回结果
return dp[n][m];
}
public static void main(String[] args) {
System.out.println(solution(3, new int[]{2, 1, 3}, new int[]{4, 2, 3}, 3) == 6);
System.out.println(solution(4, new int[]{1, 2, 3, 2}, new int[]{10, 20, 30, 40}, 5) == 70);
System.out.println(solution(2, new int[]{1, 4}, new int[]{5, 10}, 4) == 10);
}
}
知识总结:动态规划的核心思想
知识点 1:动态规划适用场景
动态规划适用于求解最优子结构问题,其核心在于通过局部最优解推导出全局最优解。
知识点 2:状态转移方程设计
状态转移方程是动态规划问题的关键,它需要根据题目特性分析不同选择之间的关系。
知识点 3:空间优化
通过一维数组优化二维数组,可以将复杂度从 O(n \times m) 减少到 O(m) 。实现时从右向左更新数组。
学习建议
初学者可以从经典问题(如0/1背包问题)入手,掌握动态规划的基本套路后再扩展到多维状态或多条件问题。
学习计划:高效刷题策略
阶段一:理解经典动态规划问题
通过以下问题掌握动态规划的基本思想:
- 最大子数组和
- 爬楼梯问题
- 简单背包问题
阶段二:分层次解决复杂问题
将问题分解为状态设计、状态转移方程和结果收集三个部分,逐步分析和实现。
阶段三:错题复盘与规律总结
利用豆包MarsCode AI平台的错题记录功能,整理动态规划问题的常见模式,并归纳适用场景。
工具运用:结合平台与资源提升学习效果
1. 算法题库与模拟练习
利用豆包MarsCode AI平台的题库进行针对性刷题,快速发现薄弱点。
2. 动态规划可视化工具
通过动态规划的在线可视化工具,观察状态转移过程,辅助理解。
3. 结合经典算法书籍
如《算法导论》中的背包问题案例,深入学习理论知识并进行验证。
结语
0/1背包问题是动态规划的经典应用,通过这道题目,我不仅加深了对动态规划的理解,也掌握了如何从问题描述中抽象出状态和转移方程。在算法学习中,保持耐心、关注细节、总结规律是提升能力的关键。希望这篇文章能为你的学习提供帮助!