backpack

中等 背包问题
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
 */





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值