題目一:
最優裝載問題,給出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 }