从问题的初始解开始,一步歩地做出当前最好的选择,逐步逼近问题的目标,尽可能得到最优解;即使得不到最优解,也可以得到最优解的近似解。
贪心算法并不是从整体最优来考虑的,它所做出的选择只是某种意义上的局部最优对许多问题都可以使用贪心算法得到整体最优解或整体最优解的近似解。
如果问题具有两个特性:
,就可以用贪心算法。
指原问题的整体最优解可以通过一系列局部最优的选择得到。
应用同一规则,将原问题变为一个相似的、但是规模更小的子问题,之后的每一步都是当前最优的选择。这种选择依赖于已经做出的选择,但不依赖于未做出的选择。(运行过程中无回溯)
当一个问题的最优解包含其子问题的最优解时,则这个问题具有最优子结构性质。
最优子结构性质是问题是否可以用贪心算法求解的关键。
举个栗子:
原问题 S = {a1 , a2 , … , ai , … , an}
通过贪心选择出一个当前最优解{ai}后,转换为求解子问题 S - {ai}。如果原问题的最优解包含子问题的最优解,则说明该问题满足最优子结构性质。
举个栗子:
问题描述:
有一天,海盗们截获了一艘装满各种各样古董的货船,每件古董都价值连城,一旦打碎就失去了价值。虽然海盗船足够大,但载重为c ,每件古董的重量为wi ,海盗们绞尽脑汁要把尽可能多的宝贝装上海盗船,该怎么办?
这是个可以用贪心算法求解的问题,要求物品数量尽可能多,那么就优先把重量小的物品放上海盗船。
思路分析:
每个古董的种类如下所示:海盗船载重c为30
将古董按照重量递增排序。
根据贪心策略,每次都选择重量最小的古董装入。
算法实现
用一维数组w[ ]存储古董的重量。
头文件:#include
double tmp = 0.0;
int res = 0; //答案
for(int i = 0; i < n ; i++){
tmp += w[i];
if(tmp <= c){
res ++;
}
else{
break;
}
}
cout << res << endl;
【算法分析】