要求要求恰裝滿背包
在初始化時除了 f[0]為 0 其它 f[1..V]均設為-∞,這樣就可以保證最終得到的f[N]是一種恰好裝滿背包的最優解。
可以這樣理解:初始化的 f 數組事實上就是在沒有任何物品可以放入背包時的合法狀態。如果要求背包恰好裝滿,那么此時只有容量為 0 的背包可能被價值為 0 的 nothing“恰好裝滿”,其它容量的背包均沒有合法的解,屬于未定義的狀態,它們的值就都應該是-∞了。如果背包并非必須被裝滿,那么任何容量的背包都有一個合法解“什么都不裝”,這個解的價值為 0,所以初始時狀態的值也就全部為 0 了。
例子 1:c[] = {4,5,6}, w[]={3,4,5} v=9
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ |
1 | 0 | -∞ | -∞ | 4 | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ |
2 | 0 | -∞ | -∞ | 4 | 5 | -∞ | -∞ | 9 | -∞ | -∞ |
3 | 0 | -∞ | -∞ | 4 | 5 | 6 | -∞ | 9 | 10 | 11 |
例子 2:c[] = { 6,3,5,4,6}, w[]={2,2,6,5,4}, v=10
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ |
1 | 0 | -∞ | 6 | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ |
2 | 0 | -∞ | 6 | -∞ | 9 | -∞ | -∞ | -∞ | -∞ | -∞ | -∞ |
3 | 0 | -∞ | 6 | -∞ | 9 | -∞ | 5 | -∞ | 11 | -∞ | 14 |
4 | 0 | -∞ | 6 | -∞ | 9 | 4 | 5 | 10 | 11 | 13 | 14 |
5 | 0 | -∞ | 6 | -∞ | 9 | 4 | 5 | 10 | 11 | 13 | 14 |
public static int zeroOneKnapsackII(int c[], int w[], int vol) {
int len = c.length;
if (len == 0 || len != w.length) {
return 0;
}
int f[] = new int[vol + 1];
for (int v = 1; v <= vol; v++)
f[v] = Integer.MIN_VALUE;
for (int i = 1; i <= len; i++) {
for (int v = vol; v >= w[i - 1]; v--) {
f[v] = Math.max(f[v], f[v - w[i - 1]] + c[i - 1]);
}
}
return f[vol];
}
區別在
** f[v] = Integer.MIN_VALUE; **