使用回溯算法解决 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
);
}
}
}