前言:
混合背包问题是一类复杂的背包问题,包含三种类型的物品:01背包物品(每种只能选一次),完全背包物品(每种可以选无限次),和多重背包物品(每种可以选有限次)。
背包问题分类:
- 0-1背包问题Java数据结构与算法(0/1背包问题)-CSDN博客
- 0-1背包问题优化Java数据结构与算法(0/1背包问题优化)-CSDN博客
- 完全背包问题 Java数据结构与算法(完全背包)-CSDN博客
- 多重背包问题Java数据结构与算法(多重背包)-CSDN博客
- 混合背包问题
- 二维背包问题
- 分组背包问题
- 有依赖的背包问题 (困难)
问题描述
给定一个容量为C
的背包和n
种物品,每种物品有一个重量weight[i]
和一个价值value[i]
。每种物品还有一个数量count[i]
,表示该物品的可用数量:
- 如果
count[i] == 1
,则该物品为01背包物品。 - 如果
count[i] == ∞
,则该物品为完全背包物品。 - 如果
1 < count[i] < ∞
,则该物品为多重背包物品。
目标是最大化背包内物品的总价值。
实现代码
public class MixedKnapsack {
public static void main(String[] args) {
int C = 10; // 背包容量
int[] weight = {2, 3, 4, 5}; // 物品重量
int[] value = {3, 4, 5, 8}; // 物品价值
int[] count = {3, 2, 1, Integer.MAX_VALUE}; // 物品数量
System.out.println(mixedKnapsack(C, weight, value, count));
}
public static int mixedKnapsack(int C, int[] weight, int[] value, int[] count) {
int n = weight.length;
int[] dp = new int[C + 1];
for (int i = 0; i < n; i++) {
if (count[i] == 1) {
// 01背包物品
for (int j = C; j >= weight[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
}
} else if (count[i] == Integer.MAX_VALUE) {
// 完全背包物品
for (int j = weight[i]; j <= C; j++) {
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
}
} else {
// 多重背包物品
for (int k = 1; k <= count[i]; k++) {
for (int j = C; j >= weight[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
}
}
}
}
return dp[C];
}
}
QA1: