核心技巧:优先队列,堆,贪心,树;
题目内容;我们要将所有的果子堆都合并在一起且每次只能合并两堆,又因为每一次合并的消耗是两堆果子的重量之和,所以我们每次和并都应选择当前情况下的重量最小的两堆,直到只剩下一堆果子;
众所周知stl中有优先队列可以直接用,但是为了锻炼自己我还是选择了手写了优先队列的相关函数,也能帮助我更好的理解优先队列。
萌新一只,有错请指出;
代码如下;
#include<iostream>
using namespace std;
int p[100010],tot;//tot是用来计数的;
void push(int x){
tot++;
p[tot]=x;
int i=tot;
int j=i/2;
while(j>0&&p[j]>p[i]&&p[j]!=0){
swap(p[i],p[j]);
i=j;
j=i/2;
}
}
int pop_front(){
return p[1];//这个其实可以不用写,只需要知道第一个是最大的直接使用就是;
}
void pop(void){
p[1]=p[tot];
tot--;
int i=1;
int j=2*i;
if(p[j]>p[j+1]&&j+1<=tot)j+=1;//子节点中肯定优先选择与小的那个交换,所以需要比较左右子节点的大小;
while(j<=tot&&p[j]<p[i]){
swap(p[j],p[i]);
i=j;
j=i*2;
if(p[j]>p[j+1]&&j<=tot-1)j+=1;//同上;
}
}
int main(){
int n;
cin>>n;
while(n--){
int b;
cin>>b;
push(b);
}
int ans=0;
for(int i=1;tot>1;i++){
int x=pop_front();
pop();
int y=pop_front();
pop();
ans+=x+y;
push(x+y);
}
cout<<ans<<endl;
return 0;
} 
京公网安备 11010502036488号