此處的最優方案是指物品總價值最大的方案。這裏以0-1揹包問題爲例。給定數據如下:
c = [2,3,4,5,6,7,8];
v = [3,4,5,6,7,8,9];
V = 23;
結合求最大總價值和方案總數兩個問題的思路,最優方案的總數可採取如下方式求解:令 表示前 i 件物品在代價爲 j 時的最大價值, 表示這個子問題的最優方案的總數。那麼可以在求解 的同時求 。分爲以下幾種情況:
- 若 或者 ,則 等於對應最優方案總數。
- 若 ,那麼 。
public int knapsackProblem(int[] c, int[] v, int V) {
int[][] dp = new int[c.length + 1][V + 1], key = new int[c.length + 1][V + 1];
for (int i = 0; i < key.length; i++) {
Arrays.fill(key[i], 1); // 初始化爲1的目的是保證任何情況下,dp[i][j]總是存在的,存在則至少爲1。
}
for (int i = 1; i <= c.length; i++) {
for (int j = V; j > 0; j--) {
dp[i][j] = dp[i - 1][j];
key[i][j] = key[i - 1][j];
if (j >= c[i - 1]) {
if (dp[i][j] < dp[i - 1][j - c[i - 1]] + v[i - 1]) {
dp[i][j] = dp[i - 1][j - c[i - 1]] + v[i - 1];
key[i][j] = key[i - 1][j - c[i - 1]];
} else if (dp[i][j] == dp[i - 1][j - c[i - 1]] + v[i - 1]) {
key[i][j] += key[i - 1][j - c[i - 1]];
}
}
}
}
System.out.println("最優方案總數: " + key[c.length][V]);
return dp[c.length][V];
}
上一篇:揹包問題之輸出最優方案