
完全背包问题的简化思路
不拿取当前物品:此时的价值与上一行同一列的价值相同,即 拿取一个物品:此时,我们需要从当前行剩余的重量 输入处理:读取物品数量n,然后依次读取每个物品的重量和价值,最后读取总容量W。 动态规划数组初始化:创建一个二维数组 初始化第一行:处理第一个物品时,只能选择拿取0个或多个。因此, 填充动态规划表:对于每个物品i和每个重量j,判断是否可以拿取当前物品。如果可以,比较不拿取和拿取当前物品两种情况,选择较大的那个值;否则,直接采用上一行的结果。 返回结果:最终返回处理完所有物品且总重量不超过W时的最大价值。
发布日期:2021-05-07 22:01:55
浏览次数:10
分类:精选文章
本文共 1851 字,大约阅读时间需要 6 分钟。
问题描述
我们需要解决一个典型的0-1背包问题:给定n个物品,每个物品都有一个重量wi和一个价值vi。我们的目标是从这些物品中选择一些,使得总重量不超过给定的容量W,同时使得所选物品的总价值最大化。
解决思路
传统的动态规划方法处理这个问题时,通常会采用以下策略:对于每个物品,我们可以选择拿取0、1、2、3...k个,然后剩余的容量中我们需要查询上一行对应的列,以找到最大的价值。然而,我们发现一个关键的优化点:对于当前物品,我们可以直接选择是否拿取它,而不是枚举所有可能的拿取次数。具体来说,我们可以这样处理:
dp[i-1][j]
。j-w[i]
中选择最优的方案,并将当前物品的价值v[i]
加到上述方案的价值上,即v[i] + dp[i][j-w[i]]
。这种方法的核心在于,当我们拿取一个物品后,剩余的重量可以继续使用同一行的动态规划结果,这样可以避免重复计算多次循环,显著降低时间复杂度。
具体代码
import java.util.Scanner;import static java.lang.Math.max;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int w[] = new int[n]; int v[] = new int[n]; for (int i = 0; i < n; i++) { w[i] = sc.nextInt(); } for (int i = 0; i < n; i++) { v[i] = sc.nextInt(); } int W = sc.nextInt(); int res = solution(w, v, n, W); System.out.println(res); sc.close(); } private static int solution(int[] w, int[] v, int n, int W) { int[][] dp = new int[n][W + 1]; // 初始化第一行与第一列 for (int i = 0; i <= W; i++) { dp[0][i] = i / w[0] * v[0]; } for (int i = 1; i < n; i++) { for (int j = 1; j <= W; j++) { if (j >= w[i]) { dp[i][j] = max(dp[i-1][j], v[i] + dp[i][j - w[i]]); } else { dp[i][j] = dp[i-1][j]; } } } return dp[n-1][W]; }}
代码解释
dp
,其中dp[i][j]
表示处理前i个物品且总重量为j时的最大价值。dp[0][i] = i / w[0] * v[0]
,即每个i的价值由第一个物品的价值决定。这种方法通过合理简化循环结构,避免了传统动态规划中的重复计算,显著提升了算法的效率。
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年03月24日 11时39分39秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
成为一个优秀数据工程师学习内容(1)
2019-03-05
红黑树学习
2019-03-05
Redis未授权访问漏洞
2019-03-05
SpringBoot整合Redis
2019-03-05
3D案例——旋转木马
2019-03-05
vue中导入导入 Mint-UI的注意事项
2019-03-05
Vue——mock模拟数据的使用
2019-03-05
Nginx配置反向代理与负载均衡
2019-03-05
socket多线程实现tcp server
2019-03-05
高阶函数reduce
2019-03-05
Lionheart万汇:布林线双底形态分析技巧
2019-03-05
Lionheart万汇:台积电大幅提升资本开支,2021有望续创辉煌
2019-03-05
Lionheart万汇:新年消费结构中贵金属交易机会
2019-03-05
LHCM万汇:在需求上升中,美国贸易赤字创下历史新高
2019-03-05
Python数据处理笔记01--numpy数组操作
2019-03-05
大力出奇迹之js文件爆破
2019-03-05
jsp技术入门
2019-03-05
线程同步机制和三个线程不安全例子
2019-03-05
Mybatis的入门01
2019-03-05
开发者社区公告【MW移动端钱包】开发公示
2019-03-05