《趣學演算法》之貪心演算法(上)

2021-09-02 02:09:34 字數 2902 閱讀 1262

乙個貪心演算法總是做出當前最好的選擇,也就是說,它期望通過區域性最優選擇從而得到全域性最優的解決方案。 ——《演算法導論》

貪心演算法秘籍

有一天,加勒比海盜們截獲了一艘裝滿古董的貨船,每件古董都價值連城,一旦打碎就失去價值。雖然海盜船足夠大,但載重量為 c,每件古董的重量為 wi ,海盜們該如何把盡可能多數量的古董裝上海盜船?

【思考過程】要求裝的古董數量盡可能多,而船的載重量固定,則優先裝重量小的物品。

【演算法設計】(1)當載重量固定為 c 時,wi 越小,可裝載的古董數量 n 越大。 (2)把 n 個古董的重量從小到大排序,根據貪心策略依次選出 i 個古董,直到海盜船裝不下。

【**實現】

#include 

#include

const int n

=1000005

;using namespase std;

double w[n]

;//古董的重量陣列

int main()

cout<<

"能裝入的古董最大數量為 ans= "

; cout

}

②阿里巴巴與四十大盜——揹包問題

假設山洞裡有 n 種寶物,每種寶物有一定重量 w 和相應的價值 v ,毛驢運載能力有限,只能運走 m 重量的寶物,一種寶物只能拿一樣,寶物可分割。那麼如何使毛驢運走最大價值的寶物?

【思考過程】如果選價值量最大的寶物,那重量不一定小,不行;如果選重量最小的寶物,那價值不一定高,也不行;每次選取單位重量價值最大的寶物,即每次選擇價效比(價值/重量)最高的寶物,達到運載重量 m ,那一定是價值最大的。

【演算法設計】(1)資料結構及初始化。將 n 種寶物的重量和價值儲存在結構體 three(含重量、價值、價效比),按價效比從高到底排序。用 sum 來儲存毛驢能夠運走的最大價值,初始量為 0。 (2)根據貪心策略,按價效比從大到小選寶物,直到達到毛驢的運載能力。每次選價效比高的物品,判斷是否小於 m ,若小於則放入,sum加上當前寶物的價值,m減去當前寶物的重量;若大於,則取該寶物的一部分 m*p[i] , m=0 ,程式結束。m減少到0,則sum得到最大值。

【**實現】

#include 

#include

const int n

=1000005

;using namespase std;

struct threes[m];

bool cmp

(three a,three b)

int main()

sort

(s,s+n,cmp)

; double sum=

0.0;

//sum表示貪心記錄運走寶物的價值之和

for(int i=

0;i)else

} cout<<

"裝入寶物的最大價值maximum value="

}

【問題拓展】0-1揹包:物品不可分割的裝載問題。

③高階鐘點秘書——會議安排

【思考過程】在會議安排中,每個會議 i 都有起始時間 bi 和結束時間 ei ,且 bi < ei ,即乙個會議進行的時間為半開區間 [bi , ei)。如果 [bi , ei)和[bj , ej) 均在「有限時間內」,且不相交,則稱會議 i 和會議 j 相容的。要讓會議數最多,我們需要選擇最多的不相交時間段。我們可以嘗試貪心策略:

(1)每次選擇開始時間最早且與已安排的會議相容的會議;(不行)

(2)每次選擇持續時間最短且與已安排的會議相容的會議;(不行)

(3)每次選擇結束時間最早且與已安排的會議相容的會議。(行)

【演算法設計】(1)初始化,將n個會議的開始時間、結束時間存放在結構體陣列中,然後按結束時間從小到大排序,結束時間相等的,按開始時間從大到小排序。 (2)選擇第乙個具有最早結束時間的會議, 用 last 記錄剛選中會議的結束時間。 (3)依次從剩下未安排的會議中選擇,若會議 i 開始時間大於等於最後乙個選中的會議的結束時間 last ,那麼會議 i 與已選中的會議相容,可以安排,更新 last 為剛選中會議的結束時間;否則,捨棄會議 i ,檢查下乙個會議是否可以安排。

【**實現】

#include 

#include

#include

using namespace std;

struct meetmeet[

1000];

//會議的最大個數為1000

class

setmeet

;//讀入資料

void setmeet:

:init()

}bool cmp

(meet x,meet y)

void setmeet:

:solve()

cout<<

"————————————————————————————————————"

"選擇的會議的過程:"

" 選擇第"

<< meet[0]

.num<<

"個會議"

ans=1;

int last = meet[0]

.end;

//記錄剛剛被選中會議的結束時間

for(i=

1;i++i)

} cout<<

"最多可以安排"

<"個會議"

<}int main()

未完待續,預知後事如何,請聽下回分解。

趣學演算法 貪心演算法 Huffman編碼

huffman編碼的原理 以字元的使用頻率作為權構建一棵哈夫曼樹,然後利用哈夫曼樹對字元進行編碼。構造一棵哈夫曼樹,是將所要編碼的字元作為葉子結點,該字元在檔案中的使用頻率作為葉子結點的權值,以 自底向上 的方式,通過n 1次 合併 運算後構造出的一棵樹。核心思想 權值越大的葉子離根越遠。貪心策略 ...

貪心演算法(上)

貪心.是好事,貪心是對的,貪心是成功的 貪心演算法 又稱 貪婪演算法 是指,在對 問題求解 時總是做出在當前看來是最好的選擇。不從整體最優上加以考慮,他所做出的僅是在某種意義上的區域性最優解。貪心演算法不是對所有問題都能得到整體最優解,但對範圍相當廣泛的許多問題他能產生整體最優解或者是整體最優解的近...

貪心演算法之prim演算法

演算法思想 首先置s 然後只要s是v的真子集,就做如下的貪心選擇 選擇滿足條件i屬於s,j屬於v s,且edge i j 是最小的邊,就將其頂點j新增到s中,這個過程一直進行到s v時為止,在這個過程中,選取到的所有邊恰好構成g的一顆最小生成樹。include define infinity 500...