NOIP 2004 合併果子

2022-03-20 08:02:31 字數 2398 閱讀 8956

洛谷p1090

jdoj 1270

在乙個果園裡,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。

每一次合併,多多可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過 n-1n−1 次合併之後, 就只剩下一堆了。多多在合併果子時總共消耗的體力等於每次合併所耗體力之和。

因為還要花大力氣把這些果子搬回家,所以多多在合併果子時要盡可能地節省體力。假定每個果子重量都為 11 ,並且已知果子的種類 數和每種果子的數目,你的任務是設計出合併的次序方案,使多多耗費的體力最少,並輸出這個最小的體力耗費值。

例如有 33 種果子,數目依次為 11 , 22 , 99 。可以先將 11 、 22 堆合併,新堆數目為 33 ,耗費體力為 33 。接著,將新堆與原先的第三堆合併,又得到新的堆,數目為 1212 ,耗費體力為 1212 。所以多多總共耗費體力 =3+12=15=3+12=15。可以證明 1515 為最小的體力耗費值。

輸入格式:

共兩行。

第一行是乙個整數 n(1\leq n\leq 10000)n(1≤n≤10000) ,表示果子的種類數。

第二行包含 nn 個整數,用空格分隔,第 ii 個整數 a_i(1\leq a_i\leq 20000)ai​(1≤ai​≤20000) 是第 ii 種果子的數目。

輸出格式:

乙個整數,也就是最小的體力耗費值。輸入資料保證這個值小於 2^231 。

輸入樣例#1: 複製

3 

1 2 9

輸出樣例#1: 複製

15

對於30%的資料,保證有n \le 1000n≤1000:

對於50%的資料,保證有n \le 5000n≤5000;

對於全部的資料,保證有n \le 10000n≤10000。

看了很多題解,覺得優先佇列的解法是最符合弱者心理貪心內涵和解題思路的。但是並沒有對優先佇列進行介紹,直接剛**,對新手和對stl不了解的童鞋很不友好。

首先要明白,#include標頭檔案裡不僅僅有迴圈佇列queue這唯一的容器可以使用,還有乙個高階的priority_queue(也就是優先佇列)可以供選手們a掉一些思路比較線性的「偽難題」。

priority_queue q;
<>裡是什麼都可以塞進去的

還有乙個比較高階的,c++內建二元組,宣告方法如下:

priority_queue< pair > q;

pair<>裡是內建二元組,尖括號裡分別指定二元組的第一元,第二元的型別。可以比較大小,以第一元為第一關鍵字,第二元為第二關鍵字。

優先佇列可以理解成乙個大根二叉堆(又來了)。

好吧我先解釋一下啥是「大根二叉堆」。

雖然這個名字有點汙,但是這是乙個很有用的資料結構,首先是二叉堆。它是一種支援插入刪除和查詢最值的資料結構。本質上是一棵滿足「堆」的性質的完全二叉樹。

二叉樹的性質不多說了。乙個h層的二叉樹,如果它是完全二叉樹,它的前h-1層都是滿的,而且最後一層的所有葉子節點(就是絕育的節點)都從左至右依次排列,那就是一棵完全二叉樹。

堆的基本性質其實就是一棵完全二叉樹,一般把堆分為3種:大根堆,小根堆和普通堆。 大根堆的定義:如果樹中任意乙個節點的權值都小於等於其父節點的權值,則成為大根堆。(通俗的說,就是越往上越大的堆) 反之則為小根堆。 普通堆麼,顧名思義就是啥也不是的堆。

插入:

q.push(x);//插入堆
刪除:

q.pop();//刪除堆頂元素
查詢:

int x=q.top();//查詢堆頂元素(最大值)

這裡注意一下時間複雜度,插入和刪除是o(logn)的,查詢是o(1)的。

考慮到過載運算子對於新手來說不是很友好,在這裡介紹乙個比較取巧的方法: 不是說優先佇列是大根堆麼?好鴨! 我把要插入元素的相反數放入堆中,拿出來的時候取反即可: 比如插入1,2,3,改為插入-1,-2,-3,此時-1最大,把-1取出的時候變為-(-1),相當於取出了最小的1。

本題根本不需要我上述的那些繁繁瑣瑣的內容,但是既然用了優先佇列,就要把優先佇列是怎麼回事搞明白,搞清楚,這樣也會對相關的資料結構有乙個更清楚的認識,以後再用也會思路更清晰。

code:

#include#include

#include

#include

#include

using

namespace

std;

intans;

priority_queue

intmain()

)

printf("%d

",ans);

return0;

}

NOIP2004普及組 合併果子

題目描述 description 在乙個果園裡,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。每一次合併,多多可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過n 1次合併之後,就只剩下一堆了。多多在合併果子時總共消...

NOIP2004 合併果子 解題報告

輸入檔案 fruit.in 輸出檔案 fruit.out 簡單對比 時間限制 1 s 記憶體限制 128 mb 在乙個果園裡,多多已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。多多決定把所有的果子合成一堆。每一次合併,多多可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可...

NOIP2004 提高組 合併果子

acwing題目鏈結 合併果子 swust oj題目鏈結 合併果子 在乙個果園裡,達達已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆。達達決定把所有的果子合成一堆。每一次合併,達達可以把兩堆果子合併到一起,消耗的體力等於兩堆果子的重量之和。可以看出,所有的果子經過n 1 n 1n 1次...