有个容量为v的背包,有n个物品,对应的重量和价值存放在数组weight[]和value[]中。物品可以放到背包中,不能超过包容量,即包里物品重量不能超过v。放到包里的物品可以重复,即物品假设有无数个。物品可以放0个或者多个
与01背包不一样,01背包,一个物品要么放,要么不放。完全背包,一个物品可以不放,或者1个,或者多个
用动态规划解决
递推公式res[i][j] = max {res[i - 1][j], res[i][j - weight[i]] + value[i] }
res[i][j]表示容量为j放i个物品的最大价值
// dp[i][j] = max{dp[i - 1][j], dp[i][j - weight[i]] + value[i]} public int completePackage(int[] weight, int[] value, int n, int v) { int[][] res = new int[n + 1][v + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= v; j++) { if (j < weight[i - 1]) res[i][j] = res[i - 1][j]; else res[i][j] = Math.max(res[i - 1][j], res[i][j - weight[i - 1]] + value[i - 1]); } } return res[n][v]; }
优化数组空间后
// dp[j] = max{dp[j], dp[j - weight[i]] + value[i]} // int[] weight = {2, 3, 4, 7}; // int[] value = {1, 3, 5, 9}; // int n = 4; // int v = 10; // res: 12 public int completePackageUseLessSpace(int[] weight, int[] value, int n, int v) { int[] res = new int[v + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j<= v; j++) { if (j >= weight[i - 1]) res[j] = Math.max(res[j], res[j - weight[i - 1]] + value[i - 1]); } } return res[v]; }