目录
贪心算法
总是做出在当前看来最好的选择,希望产生整体最优。(局部最优选择)
其他应用场景:
- 哈夫曼树
- 最短路径
- 最小生成树
例题1:找零钱问题
给定一些人民币的面额,数量不限,要求找出金额为m元且人民币张数最少的方案。
对于现行的人民币面额:1、5、10、20、50、100,我们找任何金额的零钱都可以使用贪心法求解,比如找72元 = 50 + 20 + 1*2,4张人民币即可实现。
public class Main {
public static void main(String[] args){
int[] coins = {100, 50, 20, 10, 5, 1};
int amount = 72;
change(coins, amount);
}
public static void change(int[] coins, int amount) {
int[] out = new int[coins.length];
int j = 0;
while(amount != 0) {
for(int i = 0; i < coins.length; i++) {
if(amount > coins[i]) {
out[i] = amount / coins[i];
amount = amount % coins[i];
}
}
}
for (int i : out) {
System.out.println("面额为" + coins[j++] + "的需要" + i + "张");
}
}
}
/*
输出:
面额为100的需要0张
面额为50的需要1张
面额为20的需要1张
面额为10的需要0张
面额为5的需要0张
面额为1的需要2张
*/
例题2:0-1背包问题(价值最大)
给定n种物品和一个背包,物品i的重量是Wi,价值为Vi,背包的容量为C。如何选择装入背包的物品,使得装入背包中物品的总价值最大。
贪心算法解决:每次选择单位重量价值最高的物品装入背包;直到背包装满为止。对于具体问题,用贪心算法是否能得到最优解,要经过证明才能确认。
public static void fill(int n, int c, int[] w, int[] v) {
//按物品单位重量的价值排序
sort(w, v);
int[] x = new int[n];
int i;
for(i = 0; i < n; i++) {
if(w[i] > c) {
break;
}
x[i] = 1;
c -= w[i];
}
if(i < n) {
x[i] = c / w[i];
}
}
例题3:活动安排问题
设有 n 个活动,每个活动使用同一资源,同一时间内只有一个活动能使用这一资源。每个活动的起始时间Si和结束时间Fi。如何选择使得进行活动最多。
public static void arrange(int n, int[] s, int[] f) {
int[] a = new int[n]; //活动安排标识数组,进行了设为1.
a[0] = 1;
int j = 0;
for(int i = 1; i < n; i++) {
if(s[i] >= f[j]) {
a[i] = 1;
j = i;
}else {
a[i] = 0;
}
}
}