貪心(Greedy)學習

2022-03-30 05:19:47 字數 3315 閱讀 4366

1.介紹

貪心(greedy)的演算法思想:把整個問題分解成多個步驟,在每個步驟都選取當前步驟的最優方案,直到所有步驟結束;在每一步都不考慮對後序步驟的影響,在後序步驟中也不再回頭改變前面的選擇。

簡單地說,演算法思想即「走一步看一步」目光短淺,因為往往區域性的最優組合不一定是全域性最優的,

2.例題

例1:description

最少硬幣問題:某人帶著3種面值的硬幣去購物,有1元、2元、5元的,硬幣數量不限;他需要支付m元,問怎麼支付才能使硬幣數量最少?

思路:根據常識,一般先拿出面值最大的,即5元,再拿出第二大的2元,最後才拿面值最小的1元。這個方案中硬幣總數是最少的。

#includeusing

namespace

std;

const

int num = 3

;const

int value[num] = ;

intmain(); //

記錄每種硬幣數量

cin >> money; //

輸入錢數

for(i= num-1 ;i>=0 ;i--)

for(i = num-1 ;i>=0 ;i--)

cout

<"

元硬幣數:

"<< ans[i]

}

這一例題中,用區域性最優的方法得到的結果是全域性最優,然而區域性最優不一定總是全域性最優,用貪心法一定能得到最優解嗎?

我們稍微改一下引數,就不一定能得到最優解,甚至無法算出答案

(1)不能得到最優解情形:例如硬幣面值為元,支付9元,用貪心演算法得到答案是6+2+1(讀者可以把程式改一下試試),需要3個硬幣,而最優情況為 5+4,即兩個硬幣

(2)算不出答案情形:在沒有1元硬幣時,常常得不到解,如:用元的硬幣,支付9元,用貪心法得到的解是錯誤的,得不到解,但實際上存在解9 = 5+2+2

雖然貪心演算法不一定能得到最優解,但是思路簡單、程式設計容易,因此當確定問題可以通過貪心法得到最優解,那麼就使用它。

例2:description

某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統.但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能超過前一發的高度.某天,雷達捕捉到敵國的飛彈來襲.由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈.

怎麼辦呢?多搞幾套系統唄!你說說倒蠻容易,成本呢?成本是個大問題啊.所以俺就到這裡來求救了,請幫助計算一下最少需要多少套攔截系統.

sample input

8 389 207 155 300 299 170 158 65

sample output

2

#includeint a[30001];//

儲存每個列表中最後一項(也是最小的一項)

intmain()

printf(

"%d\n

",k);//

輸出最後的列表數

}

return0;

}

例3:description:

乘船問題(入門)

題目:有n個人,第

i個人的重量為

wi,每艘船的最大載重量均為

c,且最多只能乘兩個人。用最少的船裝載所有人。

分析:貪心法!

考慮最輕的人

i,他應該和誰一起坐呢?如果每個人都無法和他一起坐船,那麼唯一的方案就是每個人坐一艘船!

否則,他應該選擇能和他一起坐船的人中最重的乙個j。

這樣的方法是貪心的!因為:它只是讓「眼前」的浪費最少。

程式實現:我們只需用兩個下標i和

j分別表示當前考慮的最輕的人和最重的人,每次先將

j往左移動,直到i和

j可以共坐一艘船,然後i加

1,j減

1。並且重複上述操作!

複雜度是o(n)。

#include #include 

#include

using

namespace

std;

const

int maxn = 10000

;int

arr[maxn];

intmain()

sort(arr+1, arr+n+1

);

int i = 1, j =n;

int ans = 0

;

while(i }

cout

<< ans + n - (2*ans)

}

例4:勇者鬥惡龍

description:

你的王國裡有一條n個頭的惡龍,你希望僱一些騎士把它殺死(即砍掉所有頭)。村里有

m個騎士可以僱傭,乙個能力值為

x的騎士可以砍掉惡龍乙個直徑不超過

x的頭,且需要支付

x個金幣。如何僱傭騎士才能砍掉惡龍的所有頭,且需要支付的金幣最少?注意,乙個騎士只能砍乙個頭(且不能被僱傭兩次)。

輸入格式

輸入包含多組資料。每組資料的第一行為正整數n和m(

1≤n,m≤

20 000

);以下

n行每行為乙個整數,即惡龍每個頭的直徑;以下

m行每行為乙個整數,即每個騎士的能力。輸入結束標誌為

n=m=0

。輸出格式

對於每組資料,輸出最少花費。如果無解,輸出「loowater

is doomed!」。

樣例輸入

2 3547

842 15510

0 0樣例輸出

11loowater is doomed!

#include#include

#include

#define maxn 200005

using

namespace

std;

intmain()

i=0;

int z=1

;

while(m--)

else

}h+=b[j++]; y++;

}if(!z)

break

; }

}if(!flag)

printf(

"loowater is doomed!\n");

else

printf(

"%d\n

",h);

}}

hdu 4221 Greedy 貪心演算法

題意 做任務,每乙個任務i都有花費時間ci,截止時間di,penalty ti di ti為第i個任務的實際完成時間,di為其截至時間,要求所有任務的penalty盡可能的小乙個 思路 貪心演算法 要求截至日期最小的應該最早完成,因為拖得越晚,penalty越大 include include us...

greedy演算法 python版

greedy演算法的核心思想是首先計算覆蓋面大的部分,然後依次尋找其他覆蓋面最大的部分。該演算法的使用場景就像他的名字一樣,當符合貪婪屬性的時候就可以考慮。states needed set 北京 上海 廣州 深圳 杭州 南京 石家莊 銀川 stations stations kone set 北京...

學習記錄2 貪心

定義 通過逐步求區域性最優 當前狀態的最好選擇 來匯出全域性最優 ps 允許的條件下貪心最快 適用條件 具有最優子結構 乙個問題的最優解包含其子問題的最優解,乙個問題的最優解包含其子問題的最優解 具有貪心選擇性質 求問題的整體最優解可以通過一系列區域性最優的選擇,即貪心選擇來達到。流程 greedy...