贪心算法----几个基本例题

题目一:

  最优装载问题,给出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 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xxpr_ybgg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值