AcWing 148. 合并果子
在一個果園里,達達已經將所有的果子打了下來,而且按果子的不同種類分成了不同的堆,
達達決定把所有的果子合成一堆,
每一次合并,達達可以把兩堆果子合并到一起,消耗的體力等于兩堆果子的重量之和,
可以看出,所有的果子經過n-1次合并之后,就只剩下一堆了,
達達在合并果子時總共消耗的體力等于每次合并所耗體力之和,
因為還要花大力氣把這些果子搬回家,所以達達在合并果子時要盡可能地節省體力,
假定每個果子重量都為1,并且已知果子的種類數和每種果子的數目,你的任務是設計出合并的次序方案,使達達耗費的體力最少,并輸出這個最小的體力耗費值,
例如有3種果子,數目依次為1,2,9,
可以先將1、2堆合并,新堆數目為3,耗費體力為3,
接著,將新堆與原先的第三堆合并,又得到新的堆,數目為12,耗費體力為12,
所以達達總共耗費體力=3+12=15,
可以證明15為最小的體力耗費值,
輸入格式
輸入包括兩行,第一行是一個整數n,表示果子的種類數,
第二行包含n個整數,用空格分隔,第i個整數ai是第i種果子的數目,
輸出格式
輸出包括一行,這一行只包含一個整數,也就是最小的體力耗費值,
輸入資料保證這個值小于231,
資料范圍
1≤n≤10000,
1≤ai≤20000
輸入樣例:
3
1 2 9
輸出樣例:
15
思路
這個把它當作一個二叉樹來坐,距離根節點最遠的數合并的次數(相加的次數)最多,所以優先選最小的兩個點,然后變成這兩個點的根節點,然后根據這些點選取最小的兩個點不斷更新,最后合并成一個堆
主要思想
哈夫曼樹
這道題我們要用小根堆來去做,小根堆找最小的兩個樹,然后更新堆,最后更新到堆的大小為1的時候,合并結束,我們要計算合并的消耗
這道題和合并石子很類似,但是合并石子合并的是相鄰的石子,這個合并不一定是相鄰的,是隨機的,
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int main(void)
{
int n;
cin>>n;
priority_queue<int,vector<int>,greater<int>> heap;
while(n--)
{
int w;
cin>>w;
heap.push(w);
}
int res=0;
while(heap.size()>1)
{
int a=heap.top();
heap.pop();
int b=heap.top();
heap.pop();
res+=a+b;
heap.push(a+b);
}
cout<<res;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/263356.html
標籤:其他
上一篇:安卓第六趴
