題解:此題爲貪心思想,實際上也是哈夫曼樹的一個構造問題,具體做法如下三種:
方法一:
首先對果子數目按從小到大順序進行排序,將第一個果子和第二個果子的數目和計算到第二個果子中,計算體力耗費值,然後利用插入排序思想將第二個果子插入到合適位置(利用此方法可節約排序空間),然後將第二個果子和第三個果子的數目和計算到第三個果子中,重複以上操作,可得最小體力耗費值
代碼實現:
#include<iostream>
#include<algorithm>
using namespace std;
int array[10005];
int main(){
int n,Strength=0;
cin>>n;
//輸入數組
for(int i=0;i<n;i++){
cin>>array[i];
}
//首次排序,目的從前開始向後合併
sort(array,array+n);
//n-1次合併
for(int i=0;i<n-1;i++){
//將i合併到i+1
array[i+1]=array[i]+array[i+1];
//計算體力消耗值
Strength+=array[i+1];
//將合併後的值插入到合適位置
int fg=array[i+1];//臨時保存待插入值
int j=i+1;
while(j<n-1){
if(fg<=array[j+1]){//找到了合適的位置插入
break;
}else{
array[j]=array[j+1];//移動
j++;
}
}
//插入
array[j]=fg;
}
//輸出力量值
cout<<Strength;
return 0;
}
方法二:
利用C++STL庫中的優先隊列,此題便成爲了送分題,因爲優先隊列具有自動排序功能,每次取隊首兩個數,計算和壓入隊列中,並使他們出隊,直到隊列還剩一個數
優先隊列可參考:優先隊列詳解
代碼實現:
#include<iostream>
#include<queue>
using namespace std;
int main(){
//定義小頂堆
priority_queue <int,vector<int>,greater<int> >q;
int n,t,heaving=0;
cin >> n;
//輸入果子數目
for(int i=0;i<n;i++){
cin >> t;
q.push(t);//壓入隊列中
}
//合併果子
while(q.size()>1){
//取前兩個最小堆
int t1 = q.top();
q.pop();
int t2 = q.top();
q.pop();
q.push(t1+t2);//將新堆壓入隊列
heaving+=t1+t2;//計算消耗體力值
}
cout<<heaving<<endl;
return 0;
}
方法三:
利用C++STL庫中的multiset集合進行解題
具體使用可參考:multiset使用詳解
具體代碼實現思路與上述方法二類似
#include<iostream>
#include<set>
using namespace std;
int main(){
multiset< int > set1;//定義集合
int n,t,heaving=0;
cin>>n;
//輸入果子數存入集合
for(int i=0;i<n;i++){
cin >> t;
set1.insert(t);
}
//開始合併堆
while(set1.size()>1){//保證剩餘1堆
int m1=*set1.begin();//獲取最小堆
set1.erase(set1.begin());//將最小堆刪除
int m2=*set1.begin();//獲取第二小堆
set1.erase(set1.begin());//將第二小堆移除
heaving+=m1+m2;//計算體力消耗值
set1.insert(m1+m2);
}
//輸出最小消耗值
cout<<heaving<<endl;
return 0;
}