01背包 动态规划 背包问题 java

一、问题描述

一共有n个物品,每件物品的重量为weight[i],价值为value[i]。

还有一个最多能装capacity的背包,问怎么装能让我的背包里的价值最大。

二、问题分析

对于容量为capacity的背包,放入物品i的时候,有两种结果:放和不放。分为三种情况讨论比较清楚。

情况一:物品i重量>包包容量。

结果:那么放不了,价值等于上次放完的物品价值

比如:weight[i]=6

           capacity = 2

情况二:物品i重量<包包容量,不放入该物品。给其他的物品机会。

结果:不放入该物品,价值等于上次放完物品价值

比如:weight =[2 3 4 5 ]

           value = [3 4 5 6]

           capacity = 5 

可以放四号物品 或者 一号和二号物品。放四号物品的价值为6 小于 放一号和二号物品的总价值7 ,所以不放四号物品。

对于情况一二来说, 价值等于上次放完的物品价值。所以我们每次放完一个物品都要记录此时书包里物品的价值。

情况三:物品i重量<包包容量,放入该物品

结果:放入该物品,价值变为value[i],书包容量变成了capacity*=capacity-weight[i]。此时,剩余的容量还可以再放其他的小重量物品

比如:物品号:1 2 3 4

           weight =[2 3 4 5 ]

           value = [1 2 4 6]

           capacity = 5 

放入物品2,capacity* = 5-3=2,还可以再放个物品一。

对于情况三,剩余的容量还可以再放其他的小重量物品。这个地方就又是一个背包问题,只不过是将书包容量变为capacity*了,这样就是重叠的子问题,所以选用动态规划来解决。剩余的capacity*可能是0~capacity的任何值。所以我们需要记录0~capacity情况下的此时书包里物品的价值。

三、动态规划

结合情况二和情况三的记录,可以知道我们需要一个二维数组来记录。

这个地方大家可以看看b站视频或者代码随想录里讲的

【动态规划】背包问题_哔哩哔哩_bilibili

代码随想录

四、代码

 public static void main(String[] args) {
        int[] weight = {1, 3, 4};
        int[] value = {15, 20, 30};
        int bagsize = 4;
        testweightbagproblem(weight, value, bagsize);
    }

    public static void testweightbagproblem(int[] weight, int[] value, int bagsize){
        int wlen = weight.length, value0 = 0;
        //定义dp数组:dp[i][j]表示背包容量为j时,前i个物品能获得的最大价值
        int[][] dp = new int[wlen + 1][bagsize + 1];
        //初始化:背包容量为0时,能获得的价值都为0
        for (int i = 0; i <= wlen; i++){
            dp[i][0] = value0;
        }
        //遍历顺序:先遍历物品,再遍历背包容量
        for (int i = 1; i <= wlen; i++){
            for (int j = 1; j <= bagsize; j++){
                if (j < weight[i - 1]){
                    dp[i][j] = dp[i - 1][j];
                }else{
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1]);
                }
            }
        }
        //打印dp数组
        for (int i = 0; i <= wlen; i++){
            for (int j = 0; j <= bagsize; j++){
                System.out.print(dp[i][j] + " ");
            }
            System.out.print("\n");
        }
    }

你可能感兴趣的:(java)