题目一:
最优装载问题,给出n个物体,第i个物体重量为wi。选择尽量多的物体,使得总重量不超过C。
经过前面的学习很容易想到贪心策略,那就是每次选重量最轻的物体,那么物体数就最多。
代码:
public class 最优装载问题 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] w = new int[n]; for (int i = 0; i < n; i++) { w[i] = sc.nextInt(); } int C = sc.nextInt(); Arrays.sort(w); int ans = f(n, w, C); System.out.println(ans); } private static int f(int n, int[] w, int c) { int sum = 0; int cnt = 0; for (int i = 0; i < n; i++) { sum += w[i]; if (sum <= c) { cnt++; } else { break; } } return cnt; } }
题目二:
部分背包问题,有n个物体,第i个物体的重量为wi,价值为vi。在总重量不超过C的情况下让总价值尽量高。每一个物体都可以只取走一部分,价值和重量按比例计算。求最大总价值。注意:每个物体可以只拿一部分,因此一定可以让总重量恰好为C。
这里可以求出物体的单价,那么贪心策略就是选择单价最高的。如果单价最高的物体的重量不足C,那就全选这个物体,如果物体的重量超过C了,那么就按比例取一部分即可。
代码:
1 import java.util.Arrays; 2 3 public class 部分背包问题 { 4 5 // 输出13.2 6 public static void main(String[] args) { 7 int[] w = { 1, 2, 3, 4, 5 }; 8 int[] v = { 3, 4, 3, 1, 4 }; 9 int n = w.length; 10 double C = 10; 11 Obj[] objs = new Obj[n]; 12 for (int i = 0; i < n; i++) { 13 objs[i] = new Obj(w[i], v[i]); 14 } 15 16 Arrays.sort(objs); 17 double c = C; 18 double maxValue = 0; 19 for (int i = n - 1; i >= 0; i--) { 20 if (objs[i].w <= c) { 21 maxValue += objs[i].v; 22 c -= objs[i].w; 23 } else { 24 maxValue += objs[i].v * (c / objs[i].w); 25 break; 26 } 27 } 28 System.out.println(maxValue); 29 } 30 31 private static class Obj implements Comparable<Obj> { 32 int w; 33 int v; 34 35 public Obj(int w, int v) { 36 this.w = w; 37 this.v = v; 38 } 39 40 public double getPrice() { 41 return v / (double) w; 42 } 43 44 @Override 45 public int compareTo(Obj o) { 46 if (this.getPrice() == o.getPrice()) 47 return 0; 48 else if (this.getPrice() < o.getPrice()) 49 return -1; 50 else 51 return 1; 52 } 53 54 @Override 55 public String toString() { 56 return "Obj{" + "w=" + w + ", v=" + v + ", price=" + getPrice() + '}'; 57 } 58 } 59 }
题目三:
乘船问题,有n个人,第i个人重量为wi。每艘船的最大载重量均为C,且最多只能乘两个人。用最少的船装载所有人。求需要最少的船的数量。
贪心策略:考虑最轻的人i,如果每个人都无法和他一起坐船(重量和超过C),则唯一的方案是每个人坐一艘。否则,他应该选择能和他一起坐船的人中最重的一个j。
代码:
1 import java.util.Arrays; 2 3 public class 乘船问题 { 4 5 // 输出6 6 public static void main(String[] args) { 7 int[] w = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 8 int n = w.length; 9 int c = 10; 10 11 Arrays.sort(w); 12 int cntOfPerson = n; 13 int cntOfBoat = 0; 14 int p1 = 0; 15 int p2 = n - 1; 16 while (cntOfPerson > 0) { 17 if (w[p1] + w[p2] > c) { 18 p2--; 19 cntOfPerson--; 20 cntOfBoat++; 21 } else { 22 p1++; 23 p2--; 24 cntOfPerson -= 2; 25 cntOfBoat++; 26 } 27 } 28 System.out.println(cntOfBoat); 29 } 30 }