【演算法•日更•第三期】最貼切的貪心演算法講解

gzr發表於2019-07-06

▎敢問此間貪心為何物?

『引入』

  在平時我們在解決一些事情時都會用到貪心的思想,我可以實誠的告訴你,你可能已經會貪心了。

  比如說,在我們買東西時,同種物品絕對是買便宜的那一家的貨啦,比如說西紅柿如果一家賣1元/斤,那麼你肯定不會買1.2元/斤的。

  再比如說:你正在打遊戲,假如突然天上掉下了一個箱子,那麼給你一個選擇,你要一個裝著大師劍的箱子,還是要一個裝著一個爛大街的小木棍的箱子,當然,你一定會選擇前者。

  如果你會這樣做,那麼,恭喜你,你已經學會貪心了。

『貪心演算法』

  貪心演算法(又稱貪婪演算法)是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解(copy自百度)

  說白了就是無論什麼情況下都要取當前最優的方法,比如說我要去學校,假如學校在南面,那麼我一定會向南走,否則都會繞遠。

『計算機例項』

  

  如上圖所示,這是一個有6個格子的方格陣,要求從每列中取出一個數,使總和最大。

  顯然,這道題是可以貪心的,只要取每列中的最大的數就可以了。

▎這麼簡單為什麼不用?

『引入』

  

  如上圖所示,這是三塊蘋果,按大小分為了大塊、中塊、小塊,那麼我們們來做一個遊戲:不限時間,一共三塊,每吃完一塊後可以接著吃剩下的,那麼比比誰吃得多。

  按照貪心的思路來說,絕對拼手速先吃到大塊,接下來呢?剩下啥吃啥唄。

  但是如果用動態規劃的思路的話,我會先吃小塊,無論對方吃中塊還是大塊,都會趕在他吃完前拿走剩下的第三塊(如果這也比不過,你直接認慫就行了),顯然,任意兩塊都會比一塊多。

『貪心不一定是最優的』

  由上面生活中的例子可以看出,貪心每次只選擇當前最優的方案,卻不在乎這個選擇對整個大問題是否最優,顯然,對於這個問題來說這是不正確的。

  這正是貪心與動態規劃的不同。

『一個正常的例子』

  還是之前的圖:

  

  但是題變了,現在我要從左下角走到右上角,求走過路徑上的最大值。

  要求:

  1)走過的格子不能再走;

  2)只能向上或向右;

  貪心演算法求解:1 -> 2 -> 4 -> 6 。

  動態規劃求解:1 -> 2 -> 10 -> 6 。

  顯然動態規劃的解才是最優的,而貪心卻不是。

 ▎怎樣才能貪心?

『貪心選擇』

  貪心選擇是指所求問題的整體最優解可以通過一系列區域性最優的選擇,即貪心選擇來達到。這是貪心演算法可行的第一個基本要素,也是貪心演算法與動態規劃演算法的主要區別。貪心選擇是採用從頂向下、以迭代的方法做出相繼選擇,每做一次貪心選擇就將所求問題簡化為一個規模更小的子問題。對於一個具體問題,要確定它是否具有貪心選擇的性質,我們必須證明每一步所作的貪心選擇最終能得到問題的最優解。通常可以首先證明問題的一個整體最優解,是從貪心選擇開始的,而且作了貪心選擇後,原問題簡化為一個規模更小的類似子問題。然後,用數學歸納法證明,通過每一步貪心選擇,最終可得到問題的一個整體最優解。(copy自百度)

  一句話概括這一堆(tuo)話:就是說必須得讓每一次的選擇都得是當前最優的。

『最優子結構』

  當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。運用貪心策略在每一次轉化時都取得了最優解。問題的最優子結構性質是該問題可用貪心演算法或動態規劃演算法求解的關鍵特徵。貪心演算法的每一次操作都對結果產生直接影響,而動態規劃則不是。貪心演算法對每個子問題的解決方案都做出選擇,不能回退;動態規劃則會根據以前的選擇結果對當前進行選擇,有回退功能。動態規劃主要運用於二維或三維問題,而貪心一般是一維問題 。(copy自百度)

  一句話概括這一堆(tuo)話:就是說這道題必須得保證每一次的當前最優選擇對於全域性來說都是最優的。


 

  因此,只有同時滿足貪心選擇和最優子結構的題才能用到貪心。

 

相關文章