5. 多重背包问题 II
作者:
dsf2
,
2021-03-04 06:33:46
,
所有人可见
,
阅读 434
import java.util.*;
class Main {
public static int knapsackWithLimitedRepeat(int[] values, int[] weights, int[] counts, int capacity) {
int n = values.length; // value index start from 1, element at index 0 is 0, so as weight
// 2D array
// int[][] dp = new int[n][capacity + 1];
// for (int i = 1; i < n; i++)
// for (int c = 0; c <= capacity; c++)
// for (int j = 0; j <= counts[i] && j * weights[i] <= c; j++)
// dp[i][c] = Math.max(dp[i][c], dp[i - 1][c - weights[i] * j] + values[i] * j);
//优化 - 二进制表示物品的个数
int[][] dp = new int[1000 * 12 + 100][capacity + 1];
int[] newValues = new int[1000 * 12 + 100];
int[] newWeights = new int[1000 * 12 + 100];
int idx = 0;
for (int i = 1; i < n; i++) {
int k = 1; // 2 ^ 0 for each items
while (k < counts[i]) {
idx++;
newValues[idx] = k * values[i];
newWeights[idx] = k * weights[i];
counts[i] -= k;
k *= 2;
}
if (counts[i] > 0) {
idx++;
newValues[idx] = counts[i] * values[i];
newWeights[idx] = counts[i] * weights[i];
}
}
n = idx + 1;
for (int i = 1; i < n; i++)
for (int c = 0; c <= capacity; c++) {
dp[i][c] = dp[i - 1][c];
if (newWeights[i] <= c)
dp[i][c] = Math.max(dp[i][c], dp[i - 1][c - newWeights[i]] + newValues[i]);
}
return dp[n - 1][capacity];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int c = sc.nextInt();
int[] values = new int[n + 1];
int[] weights = new int[n + 1];
int[] counts = new int[n + 1];
for (int i = 1; i <= n; i++) {
weights[i] = sc.nextInt();
values[i] = sc.nextInt();
counts[i] = sc.nextInt();
}
System.out.println(knapsackWithLimitedRepeat(values, weights, counts, c));
}
}