递推公式:
getPakage01():
从左往右,从上往下插值
getPakage02:
package com.dongtaiguihua;
//01背包问题
//有一堆物品,物品的价值为v[2,4,7];对应的重量w[6,5,10],背包的容量为11,计算包最多装物品的价值?(每个物品只能取一个)
public class Package01 {
public static void main(String[] args) {
int[] w = {1, 2, 5, 6, 7};//商品重量
int[] v = {1, 6, 18, 22, 28};//价值
int c = 11;//背包承重
System.out.println(getPackageMaxValue01(w, v, c));//优化空间
System.out.println(getPackageMaxValue02(w, v, c));//未优化空间
}
public static int getPackageMaxValue01(int[] w, int[] v, int c) {//优化空间
int[] p = new int[c + 1];
for (int i = c; i >= 0; i--) {//第一个物品放进容量为i的背包后,背包的价值
if (i >= w[0]) {
p[i] = v[0];
} else {//int数组默认为0,可以不写
p[i] = 0;
}
}
for (int j = 1; j < w.length; j++) {//遍历放入物品
for (int k = c; k > 0; k--) {
if (k >= w[j] && p[k - w[j]] + v[j] > p[k]) {//=号代表背包为空时放新物品
p[k] = p[k - w[j]] + v[j];
}
}
}
return p[c];
}
public static int getPackageMaxValue02(int[] w, int[] v, int C) {//未优化空间
int size = w.length;
if (size == 0) {
return 0;
}
int[][] dp = new int[size][C + 1];
//初始化第一行
//仅考虑容量为C的背包放第0个物品的情况,物品从0开始
for (int i = 0; i <= C; i++) {
dp[0][i] = w[0] <= i ? v[0] : 0;
}
//填充其他行和列
for (int i = 1; i < size; i++) {//从1号物品遍历
for (int j = 0; j <= C; j++) {
dp[i][j] = dp[i - 1][j];
if (w[i] <= j) {
dp[i][j] = Math.max(dp[i][j], v[i] + dp[i - 1][j - w[i]]);
}
}
}
return dp[size - 1][C];
}
}