演算法基礎 貪心策略

2021-09-19 15:18:57 字數 2974 閱讀 1491

本文主要作為自己的學習筆記,並不具備過多的指導意義。

概述

貪心演算法通常用來求解最優問題

由區域性最優解到整體最優解

通過不斷對區域性最優進行操作,最終達到整體最優

無後效性

後序操作,不會出現資料狀態的回滾

和dp(動態規劃)之間的聯絡

很多貪心問題可以通過dp進行求解

最優裝載問題

給出n個物體,第乙個物體重量為mi

盡量選擇最多的物品,總重不超過c

先將物品按照質量排序,然後依次放入每個物品,直到總重量將超過c位置。

這裡依次將剩餘物品中質量最小的物品放入的過程,就是貪心的過程。

合併果子

一類總過程代價,取決於子過程代價的問題

有n堆果子,沒堆果子的數量為ai,每次可以將兩堆果子合併,每次合併將消耗兩堆果子總數的體力。

求最小消耗的體力

1首先,如果我們什麼都不管直接兩兩合併:總計消耗48點體力

然後,我們嘗試排序後兩兩合併:總計消耗44點體力

最後,我們嘗試只將當前所有資料中最小的兩個進行合併:總計消耗38點體力

解法

構建乙個小根堆,每次從堆頂推出兩個元素合併。並且將合併都的元素追加進小根堆中即可。

具體證明的過程有一定難度,可以參考哈夫曼編碼證明的過程。

以上的操作過程,也就是貪心的過程。他只保證單次合併所消耗的體力最優,而不在意其他的資料該如何合併。

堆結構往往用來解決貪心的問題。因為貪心問題往往需要乙個明確的指標,最大值或者最小值。

專案利潤

輸入:

cost:每個專案的花費

profits:每個專案的利潤(純利潤)

k:最多能做k個專案

w:表示初始資金

輸出:最後可以獲得的最大錢數

1. 將cost與profits中的元素依次合併成乙個新的節點node:

public class node }
2. 準備乙個以專案花費構建的小根堆

將所有node依次放入

3. 準備乙個以專案利潤構建的大根堆

貪心過程:

從小根堆中依次彈出堆頂元素,直到node.c>w(專案所需資金大於當前資金)

具體**上,將小根堆陣列removefirst,然後將arr[0]與arr[arr.count-1]位置交換。讓小根堆對arr[0]位置元素向下調整即可。

將小根堆中彈出的元素放入大根堆中(大根堆中即為當前可執行的專案)

具體**上,將元素追加進大根堆陣列末尾,並進行調整即可。

從大根堆中彈出堆頂元素,並將w += node.p(執行收益最大的專案,並且更新當前資金)

具體**上與第一步類似

該貪心過程總計執行k次,每一次執行都只需要關心小根堆中最小值,與大根堆中最大值即可。最後的w即為最大總資產。

會議安排

在優先的時間內安排數量最多的會議

做一張圖可以直觀表示過程:我們將藍色表示為待安排,紅色表示為已安排,黑色表示為不可安排

我們可以嘗試幾種不同的貪心策略

1. 每次選擇持續時間最短的安排

顯然不可行

2. 每次選擇開始時間最早的

顯然也不可行

3. 每次選擇開始時間最早的並且持續時間最短的來安排

由此可見該方案是可以行的

**也很簡單,只需要關心當前有效資料內開始時間晚於當前會議結束時間的結束時間最早的乙個資料即可。

func bestarrange(programs:[program]) -> int     }    return res}
貪心策略的證明貪心策略的數學證明通常很複雜,有能力可以去翻閱

這裡推薦一種很方便的方式,對數器。

通過小樣本大樣本量的測試,證明貪心策略的正確性。

以排序演算法的證明舉例

var checkok = truefor i in 0..<10000 }print(checkok ? "比對成功":"比對失敗")
對於貪心問題,可能不一定存在乙個一定正確的演算法。那麼我們完全可以不去比對結果是否一致,只要貪心策略的結果永遠優於預設順序得出的結果即可。

關於對數器的介紹可以參閱另一篇

演算法策略 貪心

目錄 貪心 greedy 練習1 最優裝載問題 加勒比海盜 問題 思路 實現 練習2 零錢兌換 問題 思路 實現 貪心策略中存在的問題 注意 練習3 0 1揹包 問題 思路例項分析 實現 貪心策略,也稱為貪婪策略,每一步都採取當前狀態下最優的選擇 區域性最優解 從而希望推導出全域性最優解 貪心的應用...

貪心演算法 貪心策略 判斷子串行

題目描述為 給定字串 s 和 t 判斷 s 是否為 t 的子串行。你可以認為 s 和 t 中僅包含英文小寫字母。字串 t 可能會很長 長度 500,000 而 s 是個短字串 長度 100 字串的乙個子串行是原始字串刪除一些 也可以不刪除 字元而不改變剩餘字元相對位置形成的新字串。例如,ace 是 ...

演算法基礎 貪心演算法

貪心演算法是常見的基礎演算法,它在求解問題時總想用當前看來最好的方法去實現,而到了下一步,再用下一步時最好的方法來解決,因此有了貪心的名字。此方法不從整體去考慮,僅是在某種意義上的區域性最優求解。雖然貪心演算法不是對所有的問題都能得到整體最優解,但是面對範圍相當廣泛的很多問題時,能產生整體最優解或是...