/**
最优装载问题:
给出n个物体,第i个物体重量为wi,选择尽量多的物体,使得重量不超过c
*/
思路:
先把物体重量进行从小到大的排序,在把排序后的物体挨个放入,如果重量小于c就计数+1,否则就是大于了c直接break退出循环。
1 private static int f(int n, int[] wi, int c) { 2 int cnt = 0; 3 int sum = 0; 4 for(int i = 0; i < n; i++){ 5 sum += wi[i]; 6 if(sum <= c){ 7 cnt++; 8 }else{ 9 break; 10 } 11 } 12 return cnt; 13 } 14 public static void main(String[] args) { 15 Scanner in = new Scanner(System.in); 16 int n = in.nextInt(); 17 int[] wi = new int[n]; 18 for(int i = 0; i < n; i++){ 19 wi[i] = in.nextInt(); 20 } 21 int c = in.nextInt(); 22 Arrays.sort(wi); 23 System.out.println(f(n,wi,c)); 24 }
/**
部分背包问题:
有n个物体,第i个物体的重量为wi,价值为vi。在总重量不超过C的情况下让总价值尽量高。
每一个物体都可以只取走一部分,价值和重量按比例计算。求最大总价值
注意:每个物体可以只拿一部分,因此一定可以让总重量恰好为C。
*/
思路:
写一个物体类实现Comparable,属性有重量有价值,有构造函数,有获取总价值的方法(价值/(double)重量),compareTo中比较总价值。
主方法中先用Arrays.sor排序,排序后价值是从低到高的,所有我们循环是(i=n-1; i >=0; i--)如果当前物体的重量 <= C,那么总价值 += 当前物体的价值,且C -= 当前物体的重量,
否则就是当前物体重量 > C,那么总价值 += 当前物体的价值*( C/当前物体的重量),然后break
1 public static class Job implements Comparable<Job>{ 2 int w; 3 int v; 4 5 public Job(int w, int v) { 6 super(); 7 this.w = w; 8 this.v = v; 9 } 10 11 public double getPrice(){ 12 return v/(double)w; 13 } 14 15 @Override 16 public int compareTo(Job other) { 17 if(this.getPrice() == other.getPrice()) 18 return 0; 19 else if(this.getPrice() > other.getPrice()) 20 return 1; 21 else 22 return -1; 23 } 24 } 25 public static void main(String[] args) { 26 27 Scanner in = new Scanner(System.in); 28 int n = in.nextInt(); 29 int[] wi = new int[n]; 30 int[] vi = new int[n]; 31 for(int i = 0; i < n; i++){ 32 wi[i] = in.nextInt(); 33 } 34 for(int i = 0; i < n; i++){ 35 vi[i] = in.nextInt(); 36 } 37 double c = in.nextInt(); 38 39 Job[] jobs = new Job[n]; 40 for(int i = 0; i < n; i++){ 41 jobs[i] = new Job(wi[i], vi[i]); 42 } 43 Arrays.sort(jobs); 44 double maxValue = 0; 45 for(int i = n-1; i >=0; i--){ 46 if(jobs[i].w <= c){ 47 maxValue += jobs[i].v; 48 c -= jobs[i].w; 49 }else{ 50 maxValue += jobs[i].v*(c/jobs[i].w); 51 break; 52 } 53 } 54 System.out.println(maxValue); 55 }