0 - 1背包问题 动态规划

0-1背包问题是一个很经典的问题,使用动态规划算法来求解也是很经典的。下面我用一个例子来讲解用动态规划算法求解0-1背包问题。
假设商店中有5件东西,重量用w表示,价格用v表示
w={1,2,3,4,5},v={1,4,2,8,9} w = { 1 , 2 , 3 , 4 , 5 } , v = { 1 , 4 , 2 , 8 , 9 }
现有小偷来到店中,他带了一个袋子能装W = 8斤的东西,应怎样装才使得总价格最高呢?

可能的情况有以下几种:
1. 当装了第k件商品的时候,袋子容量超过最大容量,第k件商品装不了,只能装前k - 1件。
2. 当装了第k件商品后的容量小于袋子的最大容量,要看装划算还是不装划算:
a. 当装第k件商品时,袋子现在容量加上第k件商品的容量,价值加上第k件商品的价值
b. 当不装第k件商品时,袋子容量不变,价值不变。

public class Solution01 {
    private static int N = 5;
    private static int W = 8;
    private static int[] w={1, 2, 3, 4, 5};
    private static int[] v={1, 4, 2, 8, 9};
    public static int search(int index, int S){
        //时间复杂度O(2^n)
        if (index >= N){  //选到最后一个不往下面选
            return 0;
        }

        if(S + w[index] > W){  //重量超过,就不取了
            return 0;
        }

        //选与不选都会跳过index;
        //一个search中有两个search,要解决第一个search的时间复杂度,一定是后一个时间复杂度的两倍
        return Math.max(search(index + 1, S + w[index]) + v[index], search( index + 1, S));
    }

    public static  void main(String[] agrs){
        System.out.println(search( 0, 0));
    }
}

修改为动态规划:

public class Solution02 {
    private static int N = 5;
    private static int W = 8;
    private static int[] w={1, 2, 3, 4, 5};
    private static int[] v={1, 4, 2, 8, 9};
    private static int[] result;
    public static int solve(int index, int S){
        //空间复杂度N*W,时间复杂度N*W
        if (index >= N){  //选到最后一个,再往下面选就是0
            return 0;
        }

        if(S + w[index] > W){  //重量超过,就不取了
            return 0;
        }

        if (result[index] >= 0){
            return result[index];
        }

        result[index] = Math.max(solve(index + 1, S + w[index]) + v[index], solve( index + 1, S));
        return result[index];
    }

    public static int search(int index, int S){
        result = new int[N];

        for (int i = 0; i < N; i++){
            result[i] = -1;

        }

        return solve(index, S);
    }

    public static  void main(String[] agrs){
        System.out.println(search( 0, 0));
    }
}

修改为递推

public class Solution03 {
    //递归有从上到下的拆解过程,递推没有
    private static int N = 5;
    private static int W = 8;
    private static int[] w={1, 2, 3, 4, 5};
    private static int[] v={1, 4, 2, 8, 9};

    public static int search(int index, int S){
        //设置边界
        int[][] result = new int[N + 1][W + 1];
        for (int i = 0; i <= N; i++){
            result[i][0] = 0;
        }

        for (int j = 0; j <= W; j++){
            result[0][j] = 0;
        }

        for (int i = 1; i <= N; i++){
            for (int j = 1; j <= W; j++){
                if (j < w[i - 1]){
                    result[i][j] = result[i - 1][j];
                }else {
                    result[i][j] = Math.max(result[i - 1][j - w[i - 1]] + v[i - 1], result[i - 1][j]);
                }
            }
        }
        return result[N][W];
    }

    public static  void main(String[] agrs){
        System.out.println(search( 0, 0));
    }
}

参考:https://blog.csdn.net/liu_c_y/article/details/53233869

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值