vlambda博客
学习文章列表

什么是贪心算法(又称贪婪算法)?

反例






什么是贪心算法(又称贪婪算法)?




什么是贪心算法(又称贪婪算法)?




什么是贪心算法(又称贪婪算法)?





什么是贪心算法(又称贪婪算法)?





什么是贪心算法(又称贪婪算法)?





什么是贪心算法(又称贪婪算法)?





什么是贪心算法(又称贪婪算法)?





什么是贪心算法(又称贪婪算法)?



通过上面的例子可以发现,在这种场景下用贪心算法一定会出大问题,所以并不是所有场景都适用于贪心算法。


这种算法的本质是不管结果如何,根据某种衡量标准(吃好喝好)每次都选择最好的(一天花完所有钱才能吃好喝好)。


讲到这里大家肯定会觉得这个贪心算法不就是个鸡肋吗?实际运用中能有什么卵用。


下面狗子给大家讲一个贪心算法的正例:


正例


众所周知人民币的面值(只看元)分为:壹元,贰元,伍元,拾元,贰拾元,伍拾元和壹佰元。


什么是贪心算法(又称贪婪算法)?


来看下真实的应用场景:



什么是贪心算法(又称贪婪算法)?



什么是贪心算法(又称贪婪算法)?



什么是贪心算法(又称贪婪算法)?



什么是贪心算法(又称贪婪算法)?




通过以上场景可以看出,狗子买薯条花了四元,给了英子贰拾元,英子找零时先从最大的开始找(拾元),之后再拿较小的找(伍元和壹元),这就是贪心算法在生活中的应用。


为什么找零的时候要用贪心算法呢?

因为在不改变人民币面值的情况下,贪心算法总能得到最优解,人民币面值设计时也考虑到发行最小的面值种类,最大限度的满足任何人的需求。


以下是示例代码:

static void getRandomMoney(int money){//存储各个面值需要使用的张数 Map<Integer,Integer> moneyAmount = new LinkedHashMap<Integer,Integer>();//面值数组int[] denominationsArray = new int[]{100,50,20,10,5,1};while(money>0){for (int i=0;i<denominationsArray.length;i++){if(money>=denominationsArray[i]){ money=money-denominationsArray[i];if (moneyAmount.containsKey(denominationsArray[i])){ moneyAmount.put(denominationsArray[i],moneyAmount.get(denominationsArray[i])+1); }else{ moneyAmount.put(denominationsArray[i],1); }break; } } }
Iterator<Integer> iterator = moneyAmount.keySet().iterator();while (iterator.hasNext()){int key = iterator.next(); System.out.println("需要人民币"+key+"元,"+moneyAmount.get(key)+"张"); }
}public static void main(String[] args) { getRandomMoney(77);}




那么问题来了,在什么场景下使用贪心算法能获得最优解?

答:局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。



狗子曰:

贪心算法就像修仙论道,每一阶段都要尽可能好的锤炼根基。