優先隊列三題

      優先隊列是一種十分強大的數據結構,它保持了一種動態的有序性,對於不斷改變有入隊的操作,而又需要某種最大或最小的操作的問題是再合適不過了,通常優先隊列的實現是由最小堆或者最大堆完成的,並通過堆排序保持隊列的有序性,模擬隊列的結構,在實際比賽中要寫一個堆排序還是要一定的時間的,但是stl中queue容器中已經可以實現優先隊列,下面以三道基本的題目來演示priority_queue的作用。

聰明的木匠
Time Limit: 1000ms, Special Time Limit: 2500ms, Memory Limit: 32768KB
Total submit users: 23, Accepted users: 10
Problem 10611 : No special judgement
Problem description
    最近,一位老木匠遇到了一件非常棘手的問題。他需要將一根非常長的木棒切成N 段。每段的長度分別爲 L1 ,L2 ,…,LN 1≤L1 ,L2 ,…,LN ≤1000 ,且均爲整數)個長度單位。 ∑Li (i=1,2,…,N) 恰好就是原木棒的長度。我們認爲切割時僅在整數點處切且沒有木材損失。
  木匠發現,每一次切割花費的體力與該木棒的長度成正比,不妨設切割長度爲 1 的木棒花費 1 單位體力。例如,若 N=3 L1 =3,L2 =4,L3 =5 ,則木棒原長爲 12 ,木匠可以有多種切法,如:先將 12 切成 3+9. ,花費 12 體力,再將 9 切成 4+5 ,花費 9 體力,一共花費 21 體力;還可以先將 12 切成 4+8 ,花費 12 體力,再將 8 切成 3+5 ,花費 8 體力,一共花費 20 體力。顯然,後者比前者更省體力。
  那麼,木匠至少要花費多少體力才能完成切割任務呢?

Input
  輸入數據的第一行爲一個整數N(2≤N≤150,000)
在接下來的 N 行中,每行爲一個整數 Li (1≤Li ≤1000)

Output
  輸出數據僅有一行,爲一個整數,表示木匠最少要花費的體力。測試數據保證這個整數不大於231 -1

Sample Input
4
3
5
7
11
Sample Output
49
Problem Source
  2010年河北大學程序設計競賽 

 

最優的方法是每次切出最小的合併,顯然要使用優先隊列;

 

【問題描述】
在一個果園裏,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。每一次合併,多 多可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過n-1次合併之後,就只剩下一堆了。多多在合併果子時總共消耗 的體力等於每次合併所耗體力之和。
因爲還要花大力氣把這些果子搬回家,所以多多在合併果子時要儘可能地節省體力。假定每個果子重量都爲1,並且已知果子的種類數和每種果子的數目,你的任務是設計出合併的次序方案,使多多耗費的體力最少,並輸出這個最小的體力耗費值。
例如有3種果子,數目依次爲1,2,9。可以先將 1、2堆合併,新堆數目爲3,耗費體力爲3。接着,將新堆與原先的第三堆合併,又得到新的堆,數目爲12,耗費體力爲 12。所以多多總共耗費體力=3+12=15。可以證明15爲最小的體力耗費值。
【輸入文件】
輸入文件fruit.in包括兩行,第一行是一個整數n(1 <= n <= 10000),表示果子的種類數。第二行包含n個整數,用空格分隔,第i個整數ai(1 <= ai <= 20000)是第i種果子的數目。
【輸出文件】
輸出文件fruit.out包括一行,這一行只包含一個整數,也就是最小的體力耗費值。輸入數據保證這個值小於231。
【樣例輸入】
3
1 2 9
【樣例輸出】
15
【數據規模】
對於30%的數據,保證有n <= 1000;
對於50%的數據,保證有n <= 5000;
對於全部的數據,保證有n <= 10000。

 

合併的最優方法是合併最小的兩堆,通過優先隊列就可以輕鬆實現;

 

刪除最小值
Time Limit: 1000ms, Special Time Limit: 2500ms, Memory Limit: 32768KB
Total submit users: 8, Accepted users: 8
Problem 10604 : No special judgement
Problem description
  序列A 中有 N 個元素,序列 B 中也有 N 個元素,依次將序列 B 中的元素移進序列 A ,對於每次移進元素,首先在一行輸出序列 A 中的最小值,然後在 A 在加入該元素,接着在序列 B 中刪除該元素,接着在序列 A 中刪除剛纔輸出的最小值。

Input
  共三行,第一行給出元素數目N ,第二行給出 A 中的原始 N 個元素,第三行給出 B 中的原始 N 個元素。 1 n 10000 ,每個元素值範圍爲 [0 100000]

Output
  在每次將B中的元素移入A之前,在一行裏輸出A中所有元素的最小值。

Sample Input
3
3 9 6
5 2 10
Sample Output
3
5
2

這道題目跟到模擬題目差不多……

以上三道題目如果掌握優先隊列再去解答十分簡單,做這種優先隊列的題目,如果發現是使用優先隊列的就很簡單了(說的這都是廢話!)

stl中的優先隊列的模板:

#include <queue>

priority_queue <int> q;

這是按照從大到小的隊列;

#include <queue>

struct cmp

{

    bool operator ()(const int &i,const int &j)

    {

        return i>j;

    }

};

priority_queue <int> q;

這是從小到大的優先隊列;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章