01背包问题_回溯法_java实现

来源:互联网 发布:c语言比大小 编辑:程序博客网 时间:2024/06/04 23:23
问题描述:


需对容量为的背包进行装载。从个物品中选取装入背包的物品,每件物品的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。

输入:

多个测例,每个测例的输入占三行。第一行两个整数:nn<=10)和c,第二行n个整数分别是w1wn,第三行n个整数分别是p1pn
和 都等于零标志输入结束。

输出:

每个测例的输出占一行,输出一个整数,即最佳装载的总价值

输入样例:

2
1
1
3
2
4
0

输出样例:

1

4

//回溯法实现01背包问题import java.util.Scanner;public class Main{static int c;static int n;static int []w;static int []p;static int cw;static int cp;static int bestp;public static void main(String args[]){Scanner s=new Scanner(System.in);//n=Integer.parseInt(s.next());//c=Integer.parseInt(s.next());while(s.hasNext()){String line=s.nextLine();//读入c和nString[] sArray=line.split(" ");n=Integer.parseInt(sArray[0]);c=Integer.parseInt(sArray[1]);if(n==0&&c==0)return;if(n==0){System.out.println(0);continue;}line=s.nextLine();//读入w的行sArray=line.split(" ");w=new int[sArray.length];for(int j=0;j<sArray.length;j++){w[j]=Integer.parseInt(sArray[j]);}line=s.nextLine();//读入p的行sArray=line.split(" ");p=new int[sArray.length];for(int j=0;j<sArray.length;j++){p[j]=Integer.parseInt(sArray[j]);}System.out.println((Knapsack(p,w,c)));}}//Main///////////////////////////////////////////////////////////////////////////////////////////////     private static class Element implements Comparable{int id;//物品编号double d;private Element(int idd,double dd){id=idd;d=dd;}public int CompareTo(Object x){double xd=((Element)x).d;if(d<xd)return -1;if(d==xd)return 0;return 1;}public boolean equals(Object x){return d==((Element)x).d;}public int compareTo(Object arg0) {// TODO Auto-generated method stubreturn 0;}}//Element////////////////////////////////////////////////////////////////////////////////////////////////////     ///////////////////////////////////////////////////////////////////////////////////////////////public static int Knapsack(int []pp,int []ww,int cc){c=cc;n=pp.length-1;//n=pp.length;cw=0;cp=0;bestp=0;Element []q=new Element[n+1];//for(int i=1;i<=n;i++)//q[i-1]=new Element(i,pp[i]/ww[i]);for(int i=0;i<=n;i++)q[i]=new Element(i,pp[i]/ww[i]);//对q[]从大到小排序for(int m=0;m<q.length;m++){for(int j=m+1;j<q.length;j++){if(q[m].d<q[j].d){//                             int temp=m;//                             m=j;//                             j=temp;int temp1=q[m].id;q[m].id=q[j].id;q[j].id=temp1;double temp2=q[m].d;q[m].d=q[j].d;q[j].d=temp2;}}}p=new int[n+1];w=new int[n+1];for(int j=0;j<=n;j++){p[j]=pp[q[j].id];w[j]=ww[q[j].id];}backtrack(0);return bestp;}//knapsnackstatic void backtrack(int i){if(i>n){bestp=cp;return;}if(cw+w[i]<=c){cw+=w[i];cp+=p[i];backtrack(i+1);cw-=w[i];cp-=p[i];}if(bound(i+1)>bestp)backtrack(i+1);}//backtrackprivate static double bound(int i){double cleft=c-cw;double bound=cp;while(i<=n&&w[i]<=cleft){cleft-=w[i];bound+=p[i];i++;}if(i<=n)bound+=p[i]*cleft/w[i];return bound;}//bound}


原创粉丝点击