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

Posted 互联网之瞳

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法——几个基本例题相关的知识,希望对你有一定的参考价值。

题目一:

  最优装载问题,给出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了,那么就按比例取一部分即可。

  代码:

import java.util.Arrays;

public class 部分背包问题 {

// 输出13.2
public static void main(String[] args) {
int[] w = { 1, 2, 3, 4, 5 };
int[] v = { 3, 4, 3, 1, 4 };
int n = w.length;
double C = 10;
Obj[] objs = new Obj[n];
for (int i = 0; i < n; i++) {
objs[i] = new Obj(w[i], v[i]);
}

Arrays.sort(objs);
double c = C;
double maxValue = 0;
for (int i = n - 1; i >= 0; i--) {
if (objs[i].w <= c) {
maxValue += objs[i].v;
c -= objs[i].w;
} else {
maxValue += objs[i].v * (c / objs[i].w);
break;
}
}
System.out.println(maxValue);
}

private static class Obj implements Comparable<Obj> {
int w;
int v;

public Obj(int w, int v) {
this.w = w;
this.v = v;
}

public double getPrice() {
return v / (double) w;
}

@Override
public int compareTo(Obj o) {
if (this.getPrice() == o.getPrice())
return 0;
else if (this.getPrice() < o.getPrice())
return -1;
else
return 1;
}

@Override
public String toString() {
return "Obj{" + "w=" + w + ", v=" + v + ", price=" + getPrice() + '}';
}
}
}


题目三:  

  乘船问题,有n个人,第i个人重量为wi。每艘船的最大载重量均为C,且最多只能乘两个人。用最少的船装载所有人。求需要最少的船的数量。

  贪心策略:考虑最轻的人i,如果每个人都无法和他一起坐船(重量和超过C),则唯一的方案是每个人坐一艘。否则,他应该选择能和他一起坐船的人中最重的一个j。

  代码:

import java.util.Arrays;

public class 乘船问题 {

// 输出6
public static void main(String[] args) {
int[] w = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int n = w.length;
int c = 10;

Arrays.sort(w);
int cntOfPerson = n;
int cntOfBoat = 0;
int p1 = 0;
int p2 = n - 1;
while (cntOfPerson > 0) {
if (w[p1] + w[p2] > c) {
p2--;
cntOfPerson--;
cntOfBoat++;
} else {
p1++;
p2--;
cntOfPerson -= 2;
cntOfBoat++;
}
}
System.out.println(cntOfBoat);
}
}



以上是关于贪心算法——几个基本例题的主要内容,如果未能解决你的问题,请参考以下文章

贪心算法例题

贪心算法讲解及例题

图解啥是贪心算法?

算法_贪心算法篇

算法_贪心算法篇

MagO第四期贪心算法经典例题:货币问题