动态规划法经典问题—01背包(详细注释,通俗易懂)

 

问题引入:背包有固定容量,物品体积不同,价值不同,且同种物品只能够被放入一次,在不超过背包容量情况下求解背包能放入物品的最大价值。

 

为什么使用动态规划:物品有不同的体积,不同的价值,所以有多种物品的组合,既然有多组合,则要求出放入背包内物品组合的最优解。

首先要了解使用回溯法的两个必备条件:1.原问题具备重叠子问题  2.具有最优子结构的性质(此处可先做简单了解,理解完代码之后会融会贯通)

我对两个必备条件的理解:

原问题具备重叠子问题 :原问题内的某个小问题会被重复计算。

具有最优子结构的性质:子问题相互独立且子问题的最优解可以推出原问题的最优解

因为存在不用的子问题,所以要将每种情况都单独求解 ,使用表格的形式可以更加直观的看出每种选择的结果。

 

代码求解:

public class Main {
    public static void main(String[] args) {
        //DP动态规划问题之01背包

        int[] v = {0,2,3,4,5};//物品价值
        int[] w = {0,2,1,3,2};//物品体积
        int bagv = 9;//背包容量
        int[][] temp = new int[v.length][bagv];
        for(int i = 0;i<v.length;i++){
            for(int y = 0;y < bagv;y++){
                temp[i][y] = 0;
            }
        }
        //问题存在重复性,所以求解最优子结构
        for(int i = 1;i <= 4;i++){
            for(int j = 1;j < bagv;j++){
                //判断当前物品体积是否大于当前背包体积
                if(j<w[i]){
                    //当前物品体积大于背包体积时,则不能放入,最优解是上一个物品时,背包容量为w[j]时背包内的价值
                    temp[i][j] = temp[i-1][j];
                }else {
                    //可以放入时,有两种情况,放入或不放入,需要比较两种情况哪种使包内价值更高
                    //temp[i-1][j]是不放入此物品,就返回选上一物品时的最优解,不用考虑包容量问题
                    //temp[i-1][j-w[i]]+v[i]是放入此物品,需考虑包容量,则价值为:当前物品价值+上一物品的最优解
                    //j-w[i]是放入当前物品后包内剩余容量,包容量的每个最优解都有记录,相加即可
                    temp[i][j] = max(temp[i-1][j],temp[i-1][j-w[i]]+v[i]);
                }
            }
        }

        printArr1(temp);

    }


    //打印方法
    public static void printArr1(int[][] arr) {
        for(int x=0; x<arr.length; x++) {
            for(int y=0; y<arr[x].length; y++) {
                System.out.print(arr[x][y]+" ");
            }
            System.out.println();
        }
    }

    //二者取最大
    private static int max(int x,int y) {
        if(x>=y){
            return x;
        }else {
            return y;
        }
    }
}

运行结果:

 

由计算结果可知,14是背包所能放入物品的最大价值。 

作者才疏学浅,欢迎大家矫枉指正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值