贴一个贪心算法的概念:指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,它所做出的仅是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
先学习一道很简单、但很经典的运用贪心算法思想的题目。
package com.jiangjiang.save.arithmetic;
/**
* 关于贪心——求最大子段和:求一个数列中,相邻数字,且不限长度,其和最大可以为多少?
* @author yanjiang
*
*/
public class Test3 {
public static void main(String[] args){
int[] nums = {1,-2,3,10,-4,7,2,-5};
System.out.println("最大子段和的值为:" + maxSum(nums));
}
public static int maxSum(int[] nums){
int tempNum = 0;
int sum = 0;
for(int i=0;i<nums.length;i++){
//一旦累加的结果tempNum小于0,则将tempNum重置为下一个nums的值
if(tempNum >= 0){
tempNum += nums[i];
}else{
tempNum = nums[i];
}
//如果某次的累加之和(tempNum)比上次计算的大,那么重新给sum赋值
if(sum < tempNum){
sum = tempNum;
}
}
return sum;
}
}
输出:
最大子段和的值为:18
贪心算法并不能得到所有问题的整体最优解,相关的反例如下(摘自百度百科):
一般来说,贪心算法的证明围绕着:
整个问题的最优解一定由在贪心策略中存在的
子问题的最优解得来的。
对于例题中的3种贪心策略,都是无法成立(无法被证明)的,解释如下:
⑴贪心策略:选取价值最大者。
反例:
反例:
W=30
物品:A B C
重量:28 12 12
重量:28 12 12
价值:30 20 20
根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。
⑵贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。
⑶贪心策略:选取单位重量价值最大的物品。
反例:
W=30
物品:A B C
重量:28 20 10
价值:28 20 10
根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。
【注意:如果物品可以分割为任意大小,那么策略3可得最优解】
对于选取单位重量价值最大的物品这个策略,可以再加一条优化的规则:对于单位重量价值一样的,则优先选择重量小的!这样,上面的反例就解决了。
但是,如果题目是如下所示,这个策略就也不行了。
W=40
物品:A B C
重量:25 20 15
重量:25 20 15
价值:25 20 15
附:本题是个DP问题,用贪心法并不一定可以求得最优解,以后了解了
动态规划算法后本题就有了新的解法。
关于动态规划,我会再另一篇文章中贴一些我学习过的例子。
ps:这些例子均被网友反复证明实践,我贴上来纯为总结,与大家学习交流。
关于动态规划,我会再另一篇文章中贴一些我学习过的例子。
ps:这些例子均被网友反复证明实践,我贴上来纯为总结,与大家学习交流。