背包问题目的是在有限的容量下求得可以获得的最大值,状态转移方程为:
// f[i,j] = Max{ f[i-1,j-Wi]+Vi( j >= Wi ), f[i-1,j] }
其中i表示前i种物品可供选择,j的意思是当前使用的背包容量为j,当有i种物品可供选择时,可以容纳的最大值为
1、背包容量为j时有i-1种物品可供选择的值,即f[i-1,j]
2、有i-1个物品可供选择包容量为j减去第i和物品的重量时的值加上第i个物品的价值
两者中的较大值。
其含义分别是:
在包里不装第i个物品,即直接取 i-1种物品可供选择时的值;
装第i个物品,即在包中空出第i个物品的重量的容量可以容纳的值再加上第i个物品的价值。
直接上代码:
public class BagQuestion {
// f[i,j] = Max{ f[i-1,j-Wi]+Vi( j >= Wi ), f[i-1,j] }
public static int bestAnswer(int[] weight, int[] value, int capacity) {
if (weight == null || value == null || weight.length != value.length)
return -1;
int[][] dp = new int[weight.length][capacity + 1];
for (int i = 1; i <= capacity; i++) {
if (i >= weight[0]) {
dp[0][i] = value[0];
} else {
dp[0][i] = 0;
}
}
for (int i = 1; i < weight.length; i++) {
for (int j = 1; j <= capacity; j++) {
if (j - weight[i] >= 0)
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
else
dp[i][j] = dp[i - 1][j];
}
}
return dp[weight.length - 1][capacity];
}
public static void main(String[] args) {
int[] weight = { 1, 2, 1 };
int[] value = { 2, 7, 3 };
int maxValue = bestAnswer(weight, value, 2);
System.out.println(maxValue);
}
}