在一個果園裏,多多已經將全部的果子打了下來,並且按果子的不一樣種類分紅了不一樣的堆。多多決定把全部的果子合成一堆。
每一次合併,多多能夠把兩堆果子合併到一塊兒,消耗的體力等於兩堆果子的重量之和。能夠看出,全部的果子通過n-1次合併以後,就只剩下一堆了。多多在合併果子時總共消耗的體力等於每次合併所耗體力之和。
由於還要花大力氣把這些果子搬回家,因此多多在合併果子時要儘量地節省體力。假定每一個果子重量都爲1,而且已知果子的種類數和每種果子的數目,你的任務是設計出合併的次序方案,使多多耗費的體力最少,並輸出這個最小的體力耗費值。
例若有3種果子,數目依次爲1,2,9。能夠先將一、2堆合併,新堆數目爲3,耗費體力爲3。接着,將新堆與原先的第三堆合併,又獲得新的堆,數目爲12,耗費體力爲12。因此多多總共耗費體力=3+12=15。能夠證實15爲最小的體力耗費值。
ios
每組輸入數據包括兩行,第一行是一個整數n(1<=n<=5000),表示果子的種類數。第二行包含n個整數,用空格分隔,第i個整數ai(1<=ai<=20000)是第i種果子的數目。
數據規模:
對於30%的數據,保證有n<=1000;
對於100%的數據,保證有n<=5000。 spa
每組輸出包括一行,這一行只包含一個整數,也就是最小的體力耗費值。輸入數據保證這個值小於231。 設計
3
1 2 9
15
這道題能夠用優先隊列作,首先將每一個元素壓入小根堆,在循環的時候不斷的取頭上的值,取兩個做爲最優值(a,b),最後再彈掉。blog
結果就是不斷累加兩個元素(a,b),最後再把這次的和再壓入小根堆.隊列
#include<queue> #include<iostream> using namespace std; priority_queue<int,vector<int>,greater<int> >q;//定義小根堆 int n,x,ans; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>x; q.push(x); } while(q.size()>=2){//小於兩個的時候已經沒有意義了。 int a=q.top();//取頭最優值 q.pop();//彈掉 int b=q.top();//取頭最優值 q.pop();//彈掉 ans+=a+b;//最優值來源 q.push(a+b);//壓入當前最優值之和 } printf("%d",ans);//輸出 return 0; }
OVER!ci