什么是贪心算法(又称贪婪算法)?
反例
通过上面的例子可以发现,在这种场景下用贪心算法一定会出大问题,所以并不是所有场景都适用于贪心算法。
这种算法的本质是不管结果如何,根据某种衡量标准(吃好喝好)每次都选择最好的(一天花完所有钱才能吃好喝好)。
讲到这里大家肯定会觉得这个贪心算法不就是个鸡肋吗?实际运用中能有什么卵用。
下面狗子给大家讲一个贪心算法的正例:
正例
众所周知人民币的面值(只看元)分为:壹元,贰元,伍元,拾元,贰拾元,伍拾元和壹佰元。
来看下真实的应用场景:
通过以上场景可以看出,狗子买薯条花了四元,给了英子贰拾元,英子找零时先从最大的开始找(拾元),之后再拿较小的找(伍元和壹元),这就是贪心算法在生活中的应用。
为什么找零的时候要用贪心算法呢?
因为在不改变人民币面值的情况下,贪心算法总能得到最优解,人民币面值设计时也考虑到发行最小的面值种类,最大限度的满足任何人的需求。
以下是示例代码:
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);}
那么问题来了,在什么场景下使用贪心算法能获得最优解?
答:局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。
狗子曰:
贪心算法就像修仙论道,每一阶段都要尽可能好的锤炼根基。
