中等 背包问题
18%
通过
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]
您在真实的面试中是否遇到过这个题?
Yes
样例
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。
注意
你不可以将物品进行切割。
public class Solution {
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
public int backPack(int m, int[] A) {
boolean f[][] = new boolean[A.length + 1][m + 1];
for (int i = 0; i <= A.length; i++) {
for (int j = 0; j <= m; j++) {
f[i][j] = false;
}
}
f[0][0] = true;
for (int i = 0; i < A.length; i++) {
for (int j = 0; j <= m; j++) {
//f[i + 1][j]:前i个物品放背包,不管怎么选,能否保证大小为j
//f[i][j]:前i-1个物品放背包,不管怎么选,能否保证大小为j
f[i + 1][j] = f[i][j];//既然前i-1个选能保证,那么前i个也能保证大小为j
//第i个物品是否放入背包
//j >=A[i]:背包容量得大于第i个物品的体积
//f[i][j-A[i]]:前i-1个物品放背包,大小正好是j-A[i]
if (j >= A[i] && f[i][j - A[i]]) {
f[i + 1][j] = true;
}
} // for j
} // for i
for (int i = m; i >= 0; i--) {
if (f[A.length][i]) {
return i;
}
}
return 0;
}
}
/**
* 0 1 2 3
* A = {2,3,5,7} m = 12
* f[5][12]:
* 0 1 2 3 4 5 6 7 8 9 10 11 12
*0 [ t][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
*1 [ t][ ][ t][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
*2 [ t][ ][ t][ t][ ][ t][ ][ ][ ][ ][ ][ ][ ]
*3 [ t][ ][ t][ t][ ][ t][ ][ t][ t][ ][ t][ ][ ]
*4 [ t][ ][ t][ t][ ][ t][ ][ t][ t][ t][ t][ ][ t]
* i = 0, f[i+1][j] f[i][j] if(j>=A[i]&&f[i][j-A[i]])
* j = 0, f[1][0] = f[0][0]=t if(0>=A[0]&&)
* j = 1, f[1][1] = f[0][1]=f if(1>=A[0]&&)
* j = 2, f[1][2] = f[0][2]=f if(2>=A[0]&&f[0][0])->f[1][2]=t
* j = 3, f[1][3] = f[0][3]=f if(3>=A[0]&&f[0][1])
* j = 4, f[1][4] = f[0][4]=f if(4>=A[0]&&f[0][2])
* ...
* i = 1, f[i+1][j] f[i][j] if(j>=A[i]&&f[i][j-A[i]])
* j = 0, f[2][0] = f[1][0]=t if(0>=A[1]&&)
* j = 1, f[2][1] = f[1][1]= if(1>=A[1]&&)
* j = 2, f[2][2] = f[1][2]=t if(2>=A[1]&&)
* j = 3, f[2][3] = f[1][3]= if(3>=A[1]&&f[1][0])->f[2][3]=t
* j = 4, f[2][4] = f[1][4]= if(4>=A[1]&&f[1][1])
* j = 5, f[2][5] = f[1][5]= if(5>=A[1]&&f[1][2])->f[2][5]=t
* ...
* i = 2, f[i+1][j] f[i][j] if(j>=A[i]&&f[i][j-A[i]])
* j = 0, f[3][0] = f[2][0]=t if(0>=A[2]&&)
* j = 1, f[3][1] = f[2][1]= if(1>=A[2]&&)
* j = 2, f[3][2] = f[2][2]=t if(2>=A[2]&&)
* j = 3, f[3][3] = f[2][3]=t if(3>=A[2]&&)
* j = 4, f[3][4] = f[2][4]= if(4>=A[2]&&)
* j = 5, f[3][5] = f[2][5]=t if(5>=A[2]&&f[2][0])->f[3][5]=t
* j = 6, f[3][6] = f[2][6]= if(6>=A[2]&&f[2][1])
* j = 7, f[3][7] = f[2][7]=t if(7>=A[2]&&f[2][2])->f[3][7]=t
* j = 8, f[3][8] = f[2][8]= if(8>=A[2]&&f[2][3])->f[3][8]=t
* j = 9, f[3][9] = f[2][9]= if(9>=A[2]&&f[2][4])
* j =10, f[3][10] = f[2][10]= if(10>=A[2]&&f[2][5])->f[3][10]=t
* j =11, f[3][11] = f[2][11]= if(11>=A[2]&&f[2][6])
* j =12, f[3][12] = f[2][12]= if(12>=A[2]&&f[2][7])
*
* i = 3, f[i+1][j] f[i][j] if(j>=A[i]&&f[i][j-A[i]])
* j = 0, f[4][0] = f[3][0]=t if(0>=A[3]&&)
* j = 1, f[4][1] = f[3][1]= if(1>=A[3]&&)
* j = 2, f[4][2] = f[3][2]=t if(2>=A[3]&&)
* j = 3, f[4][3] = f[3][3]=t if(3>=A[3]&&)
* j = 4, f[4][4] = f[3][4]= if(4>=A[3]&&)
* j = 5, f[4][5] = f[3][5]=t if(5>=A[3]&&)
* j = 6, f[4][6] = f[3][6]= if(6>=A[3]&&)
* j = 7, f[4][7] = f[3][7]=t if(7>=A[3]&&f[3][0])->f[4][7]=t
* j = 8, f[4][8] = f[3][8]=t if(8>=A[3]&&f[3][1])
* j = 9, f[4][9] = f[3][9]= if(9>=A[3]&&f[3][2])->f[4][9]=t
* j =10, f[4][10] = f[3][10]=t if(10>=A[3]&&f[3][3])->f[4][10]=t
* j =11, f[4][11] = f[3][11]= if(11>=A[3]&&f[3][4])
* j =12, f[4][12] = f[3][12]= if(12>=A[3]&&f[3][5])->f[4][12]=t
*
* for (int i = m; i >= 0; i--) {
if (f[A.length][i]) {
return i;
}
}
* i=12, f[4][12]
* return 12
*/