貪心法經典例題

2021-09-25 15:48:18 字數 3095 閱讀 2541

有1元,5元,10元,50元,100元,500元的硬幣各c1,c5,c10,c50,c500枚。現在要用這些硬幣支付a元,最少需要多少枚硬幣?

輸入:3 2 1 3 0 2

620輸出:

6

#include

using

namespace std;

intmain()

;for

(int i =

0; i <

6; i++

)int a;

cin >> a;

int ans =0;

for(

int i =

5; i >=

0; i--

) cout << ans;

return0;

}

有n項工作,每項工作分別在s;時間開始,在t時間結束。對於每項工作,你都可以選擇參與與否。如果選擇了參與,那麼自始至終都必須全程參與。此外,參與工作的時間段不能重疊(即使是開始的瞬間和結束的瞬間的重疊也是不允許的)

輸入:51 2 4 6 8

3 5 7 9 10

輸出:3

分析:這個問題也是貪心(廢話,放在貪心這一節裡面),但不像前面硬幣那麼簡單。書上解釋很清楚,這裡不多說,也不做過多詳細證明(因為不想打字,而且我也不會。。。),下面給出方法和簡要證明。

結束時間越早,之後可選擇的工作越多,因此本題思路是:在可選的工作中,每次都選取結束時間最早的工作。

看書本上說,證明很複雜,但是可以按照下面方法證明:

① 與其他方案相比, 該演算法的選擇方案在選取了相同數量的更早開始的工作時,其最終結束時間

不會比其他方案的更晚。

② 所以,不存在選取更多工作的方案。

#include

#include

using

namespace std;

int start[

1005

], end[

1005];

pair<

int,

int> node[

1005];

intmain()

for(

int i =

0; i < n; i++

)for

(int i =

0; i < n; i++

)sort

(node, node + n)

;int ans =

0, t =0;

//t為結束時間

for(

int i =

0; i < n; i++)}

cout << ans << endl;

return0;

}

給定長度為n的字串s,要構造乙個長度為n的字串t,起初,t是乙個空串,隨後反覆進行下列任意操作。

① 從s的頭部刪除乙個字元,新增到t的尾部;

② 從s的尾部刪除乙個字元,新增到t的尾部;

目標是要構造字典序盡可能小的字串t。

分析:從字典序順序上看,無論t末尾多大,只要前面部分較小就行。所以只需不斷取s開頭和末尾較小的乙個字元放到t的末尾。

#include

#include

#include

using

namespace std;

intmain()

else

s1 = s;

reverse

(s1.

begin()

, s1.

end())

;}cout << t << endl;

return0;

}

乙個直線上有n個點。點i的距離是xi。從這些點中選取若干個加上標記。要求:對於每個點,與其距離為r的範圍內必有做標記的點(包括自身)。求至少標記多少點才能滿足要求。

戳這->原題poj3069

分析:顯然我們應該從最左邊開始考慮,對於這個點,距離其r以內的區域必須要有帶標記的點。因此,帶標記的點一定在次點的右側(包含這個店本身)。我們只需要在它的右側找到距離左端第乙個點的距離剛好小於或等於r(再往右就大於r),記這個點為s,那麼下乙個標記的點p就是在s的右側距離s的距離剛好小於或等於r,反覆執行該過程。

#include

using

namespace std;

int a[

10005];

intmain()

int i =

0, ans =0;

while

(i < r)

int p = a[i -1]

;//一直向右前進直到遇到距離p大於r的點

while

(i < r && a[i]

<= s + p)

ans++;}

cout << ans << endl;

return0;

}

有乙個農夫要把乙個木板巨成幾塊給定長度的小木板,每次鋸都要收取一定費用,這個費用就是當前鋸的這個木版的長度,給定各個要求的小木板的長度,及小木板的個數n,求最小費用。戳這->原題poj3253

分析:切割方法對應如下二叉樹,這裡每個葉子節點就對應切割出的一塊塊木板,葉子結點深度就對應所需切割次數,,開銷合計就是各葉子結點的木板長度 x 節點深度。

這題其實是哈夫曼思想,要使總費用最小,那麼每次只選取最小長度的兩塊木板相加,再把這些和累加到總費用中即可。這題可用優先佇列來做。

#include

#include

using

namespace std;

intmain()

long

long ans =0;

while

(!q.

empty()

) q.

push

(m1 + m2);}

cout << ans << endl;

return0;

}

貪心法(經典例題篇)

思想 不斷選取當前最優策略 例題一 硬幣問題 description 有1元 5元 10元 50元 100元 500元的硬幣各c1 c5 c10 c50 c100 c500枚。現在要用這些硬幣來支付a元,最少需要多少枚硬幣?題目一定有解。input 輸入包含多組測試用例,對於每組測試用例 輸入7個整...

貪心演算法經典例題3 飛彈發射問題

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

貪心演算法經典例子

貪心演算法總是作出在當前看來最好的選擇。也就是說貪心演算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的區域性最優選擇。基本思想 貪心演算法並不從整體最優上加以考慮,它所做的選擇只是在某種意義上的區域性最優解。基本要素 最優子結構性質和貪心選擇性質。和動態規劃區別 動態規劃演算法中,每步所做的...