0-1背包问题(几种算法解)
标题: | 0-1背包问题 |
时 限: | 1000 ms |
内存限制: | 10000 K |
总时限: | 3000 ms |
描述: |
需对容量为c 的背包进行装载。从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高。 |
输入: |
多个测例,每个测例的输入占三行。第一行两个整数:n(n<=10)和c,第二行n个整数分别是w1到wn,第三行n个整数分别是p1到pn。n 和 c 都等于零标志输入结束。 |
输出: |
每个测例的输出占一行,输出一个整数,即最佳装载的总价值。 |
输入样例: |
1 2
|
输出样例: |
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 }