使用回溯算法解决 0 1 背包问题

本文介绍如何利用回溯算法解决经典的0 1背包问题,详细描述了问题背景,即在背包容量限制下,如何选择物品以最大化总重量。文章还提及问题的进阶形式,即在考虑物品价值的情况下,如何实现最大价值。并提到通过简单修改代码即可应对这一进阶挑战。

使用回溯算法解决 0 1 背包问题

对于 0 1 背包问题,我们最高效的方法是使用动态规划来解决,但其实我们使用回溯算法也可以解决0 1背包问题

问题描述:
我们有一个背包,背包可承载的重量是Wkg。现在我们有n个物品,每个物品的重量不等,并且不可分割,我们现在期待选择几件物品装载到背包中,在不超过背包重量的前提下如何让背包中物品的总重量最大。
代码:

public class Main {
    public int maxW = Integer.MIN_VALUE;
    //cw 表示当前已经装进去的物品的重量和; i 表示考察到哪个物品了
    //w 背包的重量; items表示每个物品的重量; n表示物品个数
    public void f(int i,int cw,int[]items,int n,int w){
        if(cw==w||i==n){//cw==w 表示装满了;i==n表示已经考察完所有的物品
            if(cw > maxW) maxW = cw;
            return;
        }
        f(i+1,cw,items,n,w);//背包中不装第i个物品
        if(cw+items[i]<=w){//只有小于背包可承受重量的时候才往背包中装物品
            f(i+1,cw+items[i],items,n,w);
        }
    }
}

问题进阶:
此时每个物品不光有自己的重量,还有自己的价值,现在问如何向包中放置物品,能够使得包中物品在不超过最大重量的情况下能够达到最大价值。
其实只要对代码稍作修改就能做到

public class Main {
    //当前背包中物品的最大总价值
    public int maxValue = Integer.MIN_VALUE;
    //当前背包中物品的最大总重量
    public int sumMaxWeight = Integer.MIN_VALUE;
    public void countMaxPkg
            (int index,int sumValue,int sumWeight,
             int[] itemValue,int[] items,int maxNum,int maxWeight){
        //index 表示考察到了哪个物品,sumValue表示价值总和
        //sumWeight表示重量总和 PkgValue[] 表示每个物品的价值
        //items[] 表示每个物品的重量,maxNum表示物品的最大数量
        //maxWeight表示背包能承受的最大重量

        //如果当前重量达到了最大总重量,数量达到了最大限制
        if(index==maxNum||sumWeight==maxWeight){
            if(sumWeight<=maxWeight){
                if(maxValue<sumValue){
                    maxValue = sumValue;
                    sumMaxWeight = maxWeight;
                }
                return;
            }
        }
        countMaxPkg(index+1,sumValue,sumWeight,itemValue,items,maxNum,maxWeight);
        if(sumWeight + items[index]<=maxWeight){
            countMaxPkg(
                    index+1,
                    sumValue + itemValue[index],
                    sumWeight + items[index],
                    itemValue,
                    items,
                    maxNum,
                    maxWeight
            );
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值