现在的位置: 首页 > 综合 > 正文

0-1背包问题(几种算法解)

2013年06月14日 ⁄ 综合 ⁄ 共 2418字 ⁄ 字号 评论关闭
文章目录

 

标题: 0-1背包问题
时 限: 1000 ms
内存限制: 10000 K
总时限: 3000 ms
描述:

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

输入:

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

输出:

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

输入样例:

 

1 2
1
1
2 3
2 2
3 4
0 0

 

输出样例:

1

4

提示:  

来源:

 

回溯法

  1 import java.sql.Array;
  2 import java.util.ArrayList;
  3 import java.util.Scanner;
  4 
  5 public class Main {
  6     static double c = 0;
  7     static int n = 0;
  8     static double[] w;
  9     static double[] p;
 10     static double cw;
 11     static double cp;
 12     static double bestp;
 13 
 14     public static void main(String[] args) {
 15         // TODO Auto-generated method stub
 16         
 17         ArrayList<Integer> list=new ArrayList<Integer>();
 18         Scanner myscanner = new Scanner(System.in);
 19         n = myscanner.nextInt();
 20         c = myscanner.nextDouble();
 21         
 22         while (!(n == 0 && c == 0)) {
 23             double[] pp = new double[n + 1];
 24             double[] ww = new double[n + 1];
 25             for (int i = 1; i <= n; i++) {
 26                 ww[i] = myscanner.nextDouble();
 27             }
 28             for (int i = 1; i <= n; i++) {
 29                 pp[i] = myscanner.nextDouble();
 30             }          
 31             Knapsack(pp, ww, c);
 32             //System.out.println("最大价值为:" + bestp);
 33             list.add((int) bestp);
 34             //System.out.println("请输入背包容量n的大小:");
 35             n = myscanner.nextInt();
 36             //System.out.println("请输入背包容量c的大小:");
 37             c = myscanner.nextDouble();
 38         }
 39         
 40         for (int i = 0; i < list.size(); i++) {
 41             System.out.println(list.get(i));
 42         }
 43     }
 44 
 45     public static class Element implements Comparable {
 46         int id;
 47         double d;
 48 
 49         private Element(int idd, double dd) {
 50             id = idd;
 51             d = dd;
 52         }
 53 
 54         public int compareTo(Object x) {
 55             double xd = ((Element) x).d;
 56             if (d < xd)
 57                 return -1;
 58             if (d == xd)
 59                 return 0;
 60             return 1;
 61         }
 62 
 63         public boolean equals(Object x) {
 64             return d == ((Element) x).d;
 65         }
 66     }
 67 
 68     public static double Knapsack(double[] pp, double[] ww, double cc) {
 69         c = cc;
 70         cw = 0.0;
 71         cp = 0.0;
 72         n = pp.length - 1;
 73         bestp = 0.0;
 74 
 75         Element[] q = new Element[n];
 76 
 77         for (int i = 1; i <= n; i++) {
 78             q[i - 1] = new Element(i, pp[i] / ww[i]);
 79         }
 80 
 81         for (int i = 0; i < n; i++) {
 82             for (int j = 0; j < n - 1 - i; j++) {
 83                 if (q[j].d > q[j + 1].d) {
 84                     double temp = q[j].d;
 85                     q[j].d = q[j + 1].d;
 86                     q[j + 1].d = temp;
 87                 }
 88             }
 89         }
 90 
 91         p = new double[n + 1];
 92         w = new double[n + 1];
 93         for (int i = 1; i <= n; i++) {
 94             p[i] = pp[q[n - i].id];
 95             w[i] = ww[q[n - i].id];
 96         }
 97 
 98         backtrack(1);
 99         return bestp;
100     }
101 
102     public static void backtrack(int i) {
103         if (i > n) {
104             bestp = cp;
105             return;
106         }
107 
108         if (cw + w[i] <= c) {
109             cw += w[i];
110             cp += p[i];
111             backtrack(i + 1);
112             cw -= w[i];
113             cp -= p[i];
114         }
115 
116         if (bound(i + 1) > bestp) {
117             backtrack(i + 1);
118         }
119     }
120 
121     public static double bound(int i) {
122         double cleft = c - cw;
123         double bound = cp;
124         while (i <= n && w[i] <= cleft) {
125             cleft -= w[i];
126             bound += p[i];
127             i++;
128         }
129 
130         if (i <= n) {
131             bound += p[i] * cleft / w[i];
132         }
133 
134         return bound;
135     }
136 }

 

抱歉!评论已关闭.