回溯法——01背包问题

来源:互联网 发布:虚拟光驱 for mac 编辑:程序博客网 时间:2024/06/06 01:20

问题不多描述

直接说思路:构造解空间树。在搜索解空间树时,只要左子节点是一个可行结点,就进入其左子树。对于右子树时,先计算上界函数,以判断是否将其减去。

代码如下:(Java实现)

import java.util.Scanner;public class Knapsack {static int W;//箱子容量static int n;//物品数量static int []w;//物品重量static int []v;//物品价值static int maxValue;//最大的价值static int []x;//最佳路径static int []cx;//中间路径static int cw;//中间所取物品重量总和static int cv;//中间所去物品价值总和static void dfs(int k){if(k>=n){//出口if(cv>maxValue){maxValue=cv;for(int i=0;i<n;i++){x[i]=cx[i];}}return;} if(cw+w[k]<=W){cx[k]=1;cw+=w[k];cv+=v[k];dfs(k+1);cw-=w[k];//回溯cv-=v[k];}cx[k]=0;dfs(k+1);}public static void main(String[] args) {Scanner input=new Scanner(System.in);System.out.println("箱子容量:");W=input.nextInt();System.out.println("物品数量:");n=input.nextInt();w=new int[n];v=new int[n];x=new int[n];cx=new int[n];System.out.println("每一件物品的重量:");for(int i=0;i<n;i++){w[i]=input.nextInt();}System.out.println("每一件物品的价值:");for(int i=0;i<n;i++){v[i]=input.nextInt();}dfs(0);System.out.println("最大价值:"+maxValue);System.out.println("所取物品:");for(int i=0;i<x.length;i++){System.out.print(x[i]+" ");}}}