演算法總結之貪心演算法

2021-10-02 09:58:07 字數 2579 閱讀 5594

貪心演算法,顧名思義,就是做出對當前最有利的選擇。貪心演算法並不從整體最優考慮,而是一定意義上的區域性最優解。當然在很多情況下,貪心演算法得到的最優解也是整體上的最優解,如最短路徑問題、最小生成樹問題,一些情況下,貪心演算法得到的即使不是全域性最優解,其結果也是最優解的很好近似。當問題的精確求解變得非常困難時,使用貪心演算法對問題進行求解,也是一種可行的辦法。

但是需要注意的是貪心演算法進行求解的問題是有條件的,只能對特定型別的問題使用,也就是組合優化問題。組合優化問題首先考慮的是這個問題能不能正面解決,也就是看它能否進行規約,將其變為乙個個小問題。然後根據我們學過的知識,判斷能不能進行分治法求解,繼續觀察原問題的結構,如果問題能夠問題能繼續分解為最優子結構,就意味著我們可以使用動態規劃進行求解,這也是我們之前學過的分治法和動態規劃的求解思路。在這兩個求解思路上,如果問題不僅僅可以被規約成小的問題,並且它有最優子結構性質,同時還具備第三種性質:貪心選擇,那此時可以採取第三種方法,貪心演算法來進行問題的求解。

貪心演算法的基本思路:給定乙個初始的解出發慢慢逼近給定的目標,直至問題中的條件得到滿足無法繼續進行求解,顯然選定的初始條件會對問題的求解精度產生很大的影響。

下面對一些常見的貪心演算法的問題做一些總結歸納。

這是教科書上典型的貪心演算法,延伸出來的活動安排等問題也是一樣的。有n個課程集和一間教室,教室同時只能被乙個課程占用,每個課程有開始時間s

is_i

si​和結束時間f

if_i

fi​,現要求盡可能多的使參加的活動最大化,也就是所佔時間區間的最大化。

這道問題的貪心策略就是按照結束時間對所有課程排序,選擇結束時間盡量早的課程,然後選擇的下乙個課程開始時間晚於當前課程的結束時間。演算法得到的解為全域性最優解,貪心選擇的意義使剩餘的可安排時間最大化,從而安排最多的相容活動。

具體**為

//輸入陣列s、j為排好序的課程開始和結束陣列,a為標記選擇哪個課程的陣列,初始化為0

void greedyselector(int n, vector& s, vector& f, vector& a)

}}

演算法的時間複雜度與排序的時間複雜度相同,為o(n

logn

)o(nlogn)

o(nlog

n)。一群人乘船渡河,單個人的體重不會超過穿的載重,每條船最多載兩人並且不能超出船的載重,求最少需要多少條穿才能讓所有人都過河。

貪心策略為讓體重大的人盡量和體重小的人湊對坐船

正確性證明:abcd四個人是按照體重從大到小排序的,p

a>pb

>pc

>pd

p_a>p_b>p_c>p_d

pa​>pb

​>pc

​>pd

​,若不按照貪心策略,安排b和d坐一條船,此時a和c可能坐一條船,也可能坐不下;

若a和c可以坐一條船,那麼四個人需要兩條,分別為(a,c)和(b,d)。既然(a,c)可以,那麼(a,d),(b,d)組合同樣滿足,此時貪心策略也是需要兩條船。

若a和c不能坐上同一條船,那麼四個人需要三條船才能滿足條件,分別為a,c,(b,d),按照貪心策略,盡量保證(a,d)和(b,c)的匹配,若a、d能坐一條船,如果b、c能坐一條船,此時需要兩條船,否則需要三條船。若a、d不能做一條船,那麼a一條船,b、c一條船,d一條船,此時需要三條船

因此貪心策略的演算法總是會產生最小的坐船數量。

具體**為:

int minboat(vectorweight, int limit)

else

}return result;

}

演算法的時間複雜度與排序的時間複雜度相同,為o(n

logn

)o(nlogn)

o(nlog

n)。將繩子剪為不定長不定數量的小段,使得所有數量的小段繩子乘積最大。

貪心策略為盡量裁剪長度為3的小段繩子。

正確性證明:當繩子長度小於5時,不用裁剪;數量繼續增長,總能分解為2的累加,對於繩子拆分為2的累加情況,由於2∗2

∗2

<3∗

32*2*2<3*3

2∗2∗

2<3∗

3,因此將繩子拆分為3的小段所得乘積最大

演算法**為:

int maxrope(int len)
計算時間複雜度為冪的計算時間複雜度,為o(l

ogn)

o(logn)

o(logn

)。一條直線上有n個位置,每個位置要麼是猴子,要麼是香蕉。每只猴子只能吃一根香蕉,猴子可以吃到離它左右兩邊最遠k步遠的香蕉,求被猴子吃掉的最多香蕉數。

貪心策略為猴子吃掉從左邊第k步遠到右邊k步遠的第一根香蕉

貪心策略的證明:第x個猴子吃x左邊第k步遠到右邊k步遠的第一根香蕉a,如果不吃,那麼後面的猴子很有可能吃不到這根香蕉,並且後面的猴子可能沒有香蕉吃,那麼吃掉的香蕉數量肯定比貪心策略得到的數量小。

具體的**為:

int maxbanana(vectorline, int k)}}

}return result;

}

遍歷整個陣列,演算法的時間複雜度為o(n

)o(n)

o(n)

總結 貪心演算法 貪心演算法入門總結

英語 greedy algorithm,又稱貪婪演算法,是一種在每一步選擇中都採取在當前狀態下最好或最優 即最有利 的選擇,從而希望導致結果是最好或最優的演算法。比如在旅行推銷員問題中,如果旅行員每次都選擇最近的城市,那這就是一種貪心演算法。貪心演算法在有最優子結構的問題中尤為有效。最優子結構的意思...

總結 貪心演算法 貪心演算法 跳躍遊戲

給定乙個非負整數陣列,你最初位於陣列的第乙個位置。陣列中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最後乙個位置。示例 1 輸入 2,3,1,1,4 輸出 true 解釋 我們可以先跳 1 步,從位置 0 到達 位置 1,然後再從位置 1 跳 3 步到達最後乙個位置。示例 2 輸入...

貪心演算法總結

第一套題主要用貪心演算法來解決問題,貪心演算法簡單來說就是從區域性最優解,進而求得整體最優解,其中難點就是選擇貪心標準,貪心標準的選擇選的巧妙問題就會變的很簡單,比如第一題搬桌子的題,就是把房間轉化為對應的走廊號,問題就簡化了很多。貪心演算法的題目有的可以很簡單的看出來,常見典型的題有,揹包問題,最...