一般而言,揹包問題要求一個最優解,若要求輸出這個最優值的方案,可參照一般動態規劃問題輸出方案的方法:記錄下每個狀態的最優值是由狀態轉移方程的哪一項推出來的,也就是說,記錄下它是由哪一項決策推出來的,便可以根據這個決策找到上一個狀態,從上一個狀態接着往前推即可,這裏以0-1揹包爲例子,給定輸入如下:
c = [2,3,4,5,6,7,8];
v = [3,4,5,6,7,8,9];
V = 23;
求解最優值的狀態轉移方程爲 。再用一個數組 ,設 表示推出 的值時是採用了方程的前一項, 表示採用了方程的後一項。
public int knapsackProblem(int[] c, int[] v, int cap) {
int[][] dp = new int[c.length + 1][cap + 1], g = new int[c.length + 1][cap + 1];
List<Integer> list = new LinkedList<>();
for (int i = 1; i <= c.length; i++) {
for (int j = cap; j > 0; j--) {
if (c[i - 1] <= j) {
if (dp[i - 1][j] >= dp[i - 1][j - c[i - 1]] + v[i - 1]) {
dp[i][j] = dp[i - 1][j];
g[i][j] = 0;
} else {
dp[i][j] = dp[i - 1][j - c[i - 1]] + v[i - 1];
g[i][j] = 1;
}
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
int i = c.length, V = cap;
while (i > 0) {
if (g[i][V] == 0) {
i--;
} else {
list.add(i - 1);
V -= c[i-- - 1];
}
}
Collections.reverse(list);
System.out.println("已選擇物品下標: " + list);
return dp[c.length][cap];
}
上一篇:揹包問題之分組揹包問題
下一篇:揹包問題之最優方案總數