混合背包问题指的是对于某种物品它对应的是0-1背包,完全背包,和多成背包问题的一种。对于这种情况我们则要对物品分别处理,当然为了方便起见还是要对多重背包进行拆分。
物品有3类n种
第一类 s = -1 代表0-1背包问题
第二类 s = 0 代表可以用无限次
第三类 s > 0 代表可以用s次
代码如下:
public class Main {
static int V = 5;
static int n = 4;
static int[] v = {0, 1, 2, 3, 4};
static int[] w = {0, 2, 4, 4, 5};
static int[] s = {0, 3, 1, 3, 2};// 每个物品最多s件
static class Good {
int s, v, w;
public Good(int s, int v, int w) {
this.s = s;
this.v = v;
this.w = w;
}
}
public static void main(String[] args) {
ArrayList<Good> goods = new ArrayList();
int[] f = new int[V + 1];
for (int i = 1; i <= n; i++) {
if (s[i] <= 0) goods.add(new Good(s[i], v[i], w[i]));
else {
for (int k = i; k <= s[i]; k *= 2) {
s[i] -= k;
goods.add(new Good(-1, k * v[i], k * w[i]));
}
if (s[i] != 0)
goods.add(new Good(-1, s[i] * v[i], s[i] * w[i]));
}
}
for (Good g : goods) {
if (g.s == 0)
for (int j = g.v; j <= V; j++)
f[j] = Math.max(f[j], f[j - g.v] + g.w);
if (g.s == -1)
for (int j = V; j >= g.v; j--)
f[j] = Math.max(f[j], f[j - g.v] + g.w);
}
System.out.println(f[V]);
}
}```