5.2 0-1背包问题
import java.util.Scanner;
public class Test5_2 {
static final int M=105;
static int i,j,n,W; //n表示n个物品,W表示购物车的容量
static int[] w=new int[M]; //w[i]表示第i个物品的重量
static int[] v=new int[M]; //v[i]表示第i个物品的价值
static int cw,cp,bestp;
static int[] x=new int[M]; //表示第i个物品是否放入购物车
static int[] bestx=new int[M]; //当前最优解
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入物品的个数n:");
n=scanner.nextInt();
System.out.println("请输入购物车的容量W:");
W=scanner.nextInt();
System.out.println("请依次输入每个物品的重量w和价值v,用空格分开:");
for(i=1;i<=n;i++) {
w[i]=scanner.nextInt();
v[i]=scanner.nextInt();
}
knapsack(W,n); //背包问题求解
scanner.close();
}
public static void knapsack(int W,int n) {
cw=0; //初始化当前放入购物车的物品重量为0
cp=0; //初始化当前放入购物车的物品价值为0
bestp=0; //初始化当前最优值为0
int sumw=0; //用来统计所有物品的总重量
int sumv=0; //用来统计所有物品的总价值
for(i=1;i<=n;i++) {
sumw+=w[i];
sumv+=v[i];
}
if(sumw<=W) { //所有物品可放入购物车
bestp=sumv;
System.out.println("放入购物车的物品最大价值为:"+bestp);
System.out.println("所有的物品均放入购物车。");
return;
}
backTrack(1); //从第一层开始搜索
System.out.println("放入购物车的物品最大价值为:"+bestp);
System.out.print("放入购物车的物品序号为:");
for(i=1;i<=n;i++) {
if(bestx[i]==1)
System.out.print(i+" ");
}
System.out.println();
}
/*用于搜索空间数,t表示当前扩展结点在第t层*/
public static void backTrack(int t) {
if(t>n) { //已经到达叶子结点,记录最优值最优解
for(j=1;j<=n;j++) { //保存最优解
bestx[j]=x[j];
}
bestp=cp;
return; //保存当前最优值
}
if(cw+w[t]<=W) { //如果满足约束条件则搜索左子树即放入物品
x[t]=1; //放入购物车
cw+=w[t]; //购物车当前的重量增加
cp+=v[t]; //购物车当前的价值增加
backTrack(t+1); //递推深度优先搜索第t+1层
cw-=w[t]; //上向回归时要把增加的值减去
cp-=v[t];
}
if(bound(t+1)>bestp) { //如果满足限界条件则搜索右子树
x[t]=0; //不放入物品,当前放入物品重量价值均不改变
backTrack(t+1); //深度优先搜索第t+1层
}
}
/*计算上界,即剩余物品的总价值*/
public static int bound(int i) {
int rp=0;