一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择从而得到全局最优的解决方案。 ——《算法导论》
贪心算法秘籍
- 贪心策略(即选择当前状态下最优解决方案)
- 局部最优解
- 全局最优解
【使用贪心算法的例子:冒泡排序——贪心策略是每一次从剩下的序列中挑一个最大的数,把这些选出来的数放在一起,就得到了从大到小的排序结果。】
贪心算法应用
①加勒比海盗——最优装载问题
有一天,加勒比海盗们截获了一艘装满古董的货船,每件古董都价值连城,一旦打碎就失去价值。虽然海盗船足够大,但载重量为 C,每件古董的重量为 Wi ,海盗们该如何把尽可能多数量的古董装上海盗船?
【思考过程】要求装的古董数量尽可能多,而船的载重量固定,则优先装重量小的物品。
【算法设计】(1)当载重量固定为 C 时,Wi 越小,可装载的古董数量 n 越大。 (2)把 n 个古董的重量从小到大排序,根据贪心策略依次选出 i 个古董,直到海盗船装不下。
【代码实现】
#include <iostream>
#include <algorithm>
const int N = 1000005;
using namespase std;
double w[N]; //古董的重量数组
int main(){
double c;
int n;
cout<< "请输入载重量 c 及古董个数 n : "<<endl;
cin>>c>>n;
cout<<"请输入每个古董的重量,用空格分开: "<<endl;
for(int i=0;i<n;i++){
tmp+=w[i];
if(tmp<=c)
ans ++;
else
break;
}
cout<<"能装入的古董最大数量为 Ans= ";
cout<<ans<<endl;
return 0;
}
②阿里巴巴与四十大盗——背包问题
假设山洞里有 n 种宝物,每种宝物有一定重量 w 和相应的价值 v ,毛驴运载能力有限,只能运走 m 重量的宝物,一种宝物只能拿一样,宝物可分割。那么如何使毛驴运走最大价值的宝物?
【思考过程】如果选价值量最大的宝物,那重量不一定小,不行;如果选重量最小的宝物,那价值不一定高,也不行;每次选取单位重量价值最大的宝物,即每次选择性价比(价值/重量)最高的宝物,达到运载重量 m ,那一定是价值最大的。
【算法设计】(1)数据结构及初始化。将 n 种宝物的重量和价值存储在结构体 three(含重量、价值、性价比),按性价比从高到底排序。用 sum 来存储毛驴能够运走的最大价值,初始量为 0。 (2)根据贪心策略,按性价比从大到小选宝物,直到达到毛驴的运载能力。每次选性价比高的物品,判断是否小于 m ,若小于则放入,sum加上当前宝物的价值,m减去当前宝物的重量;若大于,则取该宝物的一部分 m*p[i] , m=0 ,程序结束。m减少到0,则sum得到最大值。
【代码实现】
#include <iostream>
#include <algorithm>
const int N = 1000005;