有4个物品,每个物品有两个属性:重量和价值。
weight
数组表示的是物品的重量,value
数组表示的是物品的价值。
每个物品有且只有一个
。
int[] weight = {2, 3, 4, 5};
int[] value = {3, 4, 5, 8};
给定一个背包,其容量为capacity
,比如capacity
可以为8,请求出背包可以装载的最大价值。
解题思路:
定义一个二维dp数组,
int[][] dp = new int[weight.length + 1][capacity + 1];
dp[k][m]
表示对于前
k
k
k个(
k
k
k从1开始计数)物品,容量为
m
m
m的背包所能装下的最大价值。
特别的,dp[0][j]
都是0,表示0个物品的最大价值为0;dp[i][0]
都是0,表示容量为0的背包所能装下的最大价值是0
下面是参考代码
package cn.shanxiaokai.beibao.beibao01;
public class Main {
public static void main(String[] args) {
int[] w = {4, 2, 3, 5};
int[] v = {5, 3, 4, 8};
int capacity = 8;
System.out.println(findAnswer(w, v, capacity));
}
private static int findAnswer(int[] w, int[] v, int capacity) {
int len = w.length;
assert w.length == v.length;
// dp[i][j] 表示对于前i个物品装进容量为j的背包的最大价值
int[][] dp = new int[len + 1][capacity + 1];
// 显示初始化
// 0个物品时,背包所能装的最大价值是0
for (int i = 0; i <= capacity; i++) {
dp[0][i] = 0;
}
// 背包容量为0时,背包所能装的最大价值是0
for (int i = 0; i <= len; i++) {
dp[i][0] = 0;
}
for (int i = 1; i <= len; i++) {
for (int j = 1; j <= capacity; j++) {
// 如果第i个物品大于当前背包容量,则放不下,尝试放前i - 1个物品
// 由于w[] v[] 的索引从0开始,所以此处是 i - 1
if (w[i - 1] > j) {
dp[i][j] = dp[i - 1][j];
} else {
// 不选当前的物品
int a = dp[i - 1][j];
// 选择当前的物品,放进背包
int b = v[i - 1] + dp[i - 1][j - w[i - 1]];
dp[i][j] = Math.max(a, b);
}
}
}
return dp[len][capacity];
}
}