2464 合併果子

2021-08-21 05:45:47 字數 2001 閱讀 8517

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

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

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

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

輸入包括兩行,第一行是乙個整數n,表示果子的種類數。

第二行包含n個整數,用空格分隔,第i個整數a[i]是第i種果子的數目。

輸出包括一行,這一行只包含乙個整數,也就是最小的體力耗費值。輸入資料保證這個值小於2^31。 3

1 2 9

1530%的資料:n≤1000;

50%的資料:n≤5000;

100%的資料:n≤10000,1≤a[i]≤20000。

第一次寫部落格那就認真一點。。。

作為初三蒟蒻,我好像剛剛才學會怎麼用堆。普及一下如何呼叫系統堆

首先我們需要定義堆,這是兩種堆定義方式:

大根堆 priority_queue《型別》 q;

小根堆 priority_queue《型別,vector《型別》,greater《型別》 > q;

//不要忘了加上標頭檔案 #include "queue"

大根堆顧名思義,較大的數在上,較小的數在下,而小根堆正好相反。

某學長跟我說,他分不清大根堆小根堆,每次都要試一下才行,這的確是一種很好的方法(對於保送北大的他來說

堆的常用操作和佇列差不多:

q.top() 取堆頂(大根堆取出最大的數,小根堆則取出最小的)

q.pop() 將堆頂出堆(這個描述不是很準確……但是應該能聽懂的)

q.push(……) 在堆中放入元素

q.empty() 判斷堆空(空則返回true)

預備知識就這麼多了,下面分析題目

首先這道題的tag就是貪心+堆,也是堆的入門題。每次合併兩堆,合併結果加入答案,那麼有很多堆會被重複加入答案。為了使答案最小,我們盡可能讓較小的堆多次加入答案,而較大的堆盡量少加入答案。那麼我們就需要乙個容器,讓每次取出來的兩個堆是所有堆中最小的。很自然想到用小根堆維護。

1)將每次讀入的數放入堆中 2)取出堆頂兩個元素,相加加入答案中,並且將它們的和入堆,直到堆中只剩乙個元素為止 3)輸出答案

**構成很簡潔

#include "stdio.h"

#include "queue"

#include "iostream"

#include "algorithm"

using namespace std;

int n,a;

priority_queue,greater> q;

int main()

int ans=0;

while(1)

y=q.top();

q.pop();

ans+=x+y; //更新答案

q.push(x+y); //和放入堆中

} return 0;

}

over~

希望大佬耐心指正

祝我和學長99(✺ω✺)

合併果子(multiset)

time limit 1 sec memory limit 128 mb submit 312 solved 113 submit status web board 現在有n堆果子,第i堆有ai個果子。現在要把這些果子合併成一堆,每次合併的代價是兩堆果子的總果子數。求合併所有果子的最小代價。第一行包...

swustoj合併果子

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

1588 合併果子

time limit 1 sec memory limit 128 mb submitted 1729 solved 783 現在有n堆果子,第i堆有ai個果子。現在要把這些果子合併成一堆,每次合併的代價是兩堆果子的總果子數。求合併所有果子的最小代價。第一行包含乙個整數t t 50 表示資料組數。每...