01背包问题

1.需求:在可容纳重量最多4磅的背包中,所能够装入的最大价值是多少。所装入的东西不能重复,即所谓的01.

商品对应的重量和价值:
在这里插入图片描述

2.思路:
w[i]:表第i个物品的重量
v[i]:表物品的价值
v[i][j]:在前i个物品中,能够装入的容量为j的背包中的最大价值

每次遍历到第i个元素,根据w[i]的值决定要不要放进去。

所以;


1.当v[i][0]=v[0][j]=0;
2.当w[i]>j:v[i][j]=v[i-1][j];
3.当j>=w[i],v[i][j]=v[i-1][j]+v[][]

代码:

package com;

import java.util.Arrays;

public class KnapsackProblem {

    public static void main(String[] args) {
        //
        int []w={1,4,3}; //物品的重量
        int []val={1500,3000,2000};  //物品的价值
        int n=val.length;  //物品的个数

        int m=4;  //背包的容量

        //创建二维数组,v[i][j]表示:前i个物品中能够装入容量为j的背包中年的最大价值
        int [][]v=new int[n+1][m+1];  //第一行第一列为0 即物品为0或背包容量为0时都是0

        //为了记录商品的情况,创建一个二维数组
        int [][]path=new int[n+1][m+1];

        //开始动态规划处理
        for(int i=1;i<v.length;i++){
            for(int j=1;j<v[0].length;j++){
                if(w[i-1]>j){
                    v[i][j]=v[i-1][j];  //v[i-1]这个代表的是val,val是从0开始的,所以这里需要减1
                }else{

                    //所以这里的v[i-1]对应到val那里就是val[i]
                    //v[i][j]=Math.max(v[i-1][j],val[i-1]+v[i-1][j-w[i-1]]);
                    //为了记录商品存放到背包的情况,就需要确定他到底走的是那一路,使用if-else来体现
                    if(v[i-1][j]<v[i-1][j-w[i-1]]+val[i-1]){
                        v[i][j]=v[i-1][j-w[i-1]]+val[i-1];
                        //把当前情况记录
                        path[i][j]=1;
                    }else{
                        v[i][j]=v[i-1][j];
                    }
                }
            }
        }
     for(int[] a:v){
         System.out.println(Arrays.toString(a));
     }
        System.out.println("--------------------");

     //倒着遍历(实际上就是分析了最后一种情况)
    int i=path.length-1;  //行的最大下标
    int j=path[0].length-1;  //列的最大下标
    while(i>0&&j>0){
        if(path[i][j]==1){
            System.out.printf("第%d个商品放入背包\n",i);
            j-=w[i-1];
        }
        i--;
    }

    }
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值