前言:
多重背包问题(Multiple Knapsack Problem, MKP)是背包问题的一个变种。在这种问题中,你有多个背包,每个背包都有一定的容量。你需要选择一些物品放入这些背包中,以使放入物品的总价值最大化。每个物品都有一个价值和一个重量,并且可以被放入一个或多个背包中,但每个物品只能使用有限的次数。
问题描述
背包问题分类:
- 0-1背包问题 Java数据结构与算法(0/1背包问题)-CSDN博客
- 0-1背包问题优化Java数据结构与算法(0/1背包问题优化)-CSDN博客
- 完全背包问题 Java数据结构与算法(完全背包)-CSDN博客
- 多重背包问题Java数据结构与算法(多重背包)-CSDN博客
- 混合背包问题
- 二维背包问题
- 分组背包问题
- 有依赖的背包问题 (困难)
解题思路:
-
输入参数:
values
: 每个物品的价值数组。weights
: 每个物品的重量数组。quantities
: 每个物品的数量限制数组。capacities
: 每个背包的容量数组。
-
数据转换:
- 将每种物品根据其数量限制转换为多个单一物品,以便于使用 0/1 背包的逻辑进行处理。
-
动态规划:
- 使用一维数组
dp
来保存当前容量下的最大价值。 - 通过更新
dp
数组,逐步计算每个容量下的最优解。
- 使用一维数组
-
结果计算:
- 最后计算每个背包的最大容量下的最大值。
实现代码
import java.util.ArrayList;
import java.util.List;
public class MultipleKnapsack {
public static void main(String[] args) {
int[] values = {60, 100, 120};
int[] weights = {10, 20, 30};
int[] quantities = {2, 1, 1};
int[] capacities = {50, 50};
int maxValue = multipleKnapsack(values, weights, quantities, capacities);
System.out.println("Maximum value: " + maxValue);
}
public static int multipleKnapsack(int[] values, int[] weights, int[] quantities, int[] capacities) {
int n = values.length;
int m = capacities.length;
// Transform each item into multiple items based on its quantity
List<Integer> newValues = new ArrayList<>();
List<Integer> newWeights = new ArrayList<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < quantities[i]; j++) {
newValues.add(values[i]);
newWeights.add(weights[i]);
}
}
int[] dp = new int[sum(capacities) + 1];
// Apply 0/1 Knapsack logic for each of the new items
for (int k = 0; k < newValues.size(); k++) {
int value = newValues.get(k);
int weight = newWeights.get(k);
for (int c = sum(capacities); c >= weight; c--) {
dp[c] = Math.max(dp[c], dp[c - weight] + value);
}
}
// Find the maximum value fitting into the combined capacity
int maxValue = 0;
for (int cap : capacities) {
maxValue = Math.max(maxValue, dp[cap]);
}
return maxValue;
}
private static int sum(int[] array) {
int sum = 0;
for (int num : array) {
sum += num;
}
return sum;
}
}
QA1: