假设你有个最大载重量为300kg300kg300kg的背包,有4个物品。它们的重量分别为123kg,88kg,93kg,100kg123kg,88kg,93kg,100kg123kg,88kg,93kg,100kg,价值分别为$$10,$19,$8,$20$。
请问背包内最大可以放入多少价值的物品?
这个问题被称为01背包问题,是典型的动态规划例题。
这里的价值是我们要优化的目标值,物品数目和重量为两个状态,所以依据这两个状态可以定义二维dp数组。
对于每个物品,我们有两种选择,即放入背包或者不放入背包。
我们设数组f[n][w]代表前n个物品在w容量的背包里可以放入的最大价值。
当没有物品或者背包容量为0时,价值显然是0:
f[0][w]=f[n][0]=0f[0][w] = f[n][0] = 0 f[0][w]=f[n][0]=0
我们求解的是背包内的物品价值最大化,则状态转移为:
f[i][j]={f[i−1][j],w[i]>jmax(f[i−1][j],f[i−1][j−w[i]]+v[i]),w[i]≤jf[i][j] = \begin{cases} f[i-1][j] &, w[i]>j \\ max(f[i-1][j],f[i-1][j-w[i]] + v[i]) &, w[i] \leq j \end{cases} f[i][j]={f[i−1][j]max(f[i−1][j],f[i−1][j−w[i]]+v[i]),w[i]>j,w[i]≤j
Java
public class mian {static int maxVal(int[] w,int[] v,int maxw) {int n = w.length;int[][] f = new int[n][maxw+1];for (int i = 1; i < n; i++) {for (int j = 1; j <= maxw; j++) {if (j < w[i]) {f[i][j] = f[i-1][j];} else {f[i][j] = Math.max(f[i-1][j-w[i]] + v[i],f[i-1][j]);}}}return f[n-1][maxw];}public static void main(String[] args) {int[] w = {123, 88, 93, 100};int[] v = {10, 19, 8, 20};int maxw = 300;System.out.println(maxVal(w,v,maxw)); // 47}
}