合併果子(優先隊列)

題目描述

在一個果園裏,多多已經將全部的果子打了下來,並且按果子的不一樣種類分紅了不一樣的堆。多多決定把全部的果子合成一堆。 
每一次合併,多多能夠把兩堆果子合併到一塊兒,消耗的體力等於兩堆果子的重量之和。能夠看出,全部的果子通過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

相關文章
相關標籤/搜索