洛谷地址:https://www.luogu.org/problemnew/show/P1090
白书第五版:448页
(1)分析图
堆策略:3+12=15 为最小合并力气
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; int heap_size,n; int heap[30001]; void put(int d) { //入堆, 完全二叉树最后一个元素入堆后并维护堆 int now,next; heap[++heap_size]=d; now=heap_size; while(now>1) { next=now/2; //next是父节点 if(heap[now]>=heap[next]) break; //小根堆 swap(heap[now],heap[next]); now=next; } } int get( ) { //出堆 int now,next,res; res=heap[1]; //第一个出堆 heap[1]= heap[heap_size--]; //最后面一个调整到第一个 now=1; while(now*2<=heap_size) { next=now*2; if(next<heap_size&&heap[next+1]<heap[next]) next++; //next标记最小的 if(heap[now]<=heap[next]) break; //维护小根堆 else swap(heap[now],heap[next]); now=next; } return res; //弹出堆顶 } void work() { int i,x,y,ans=0; cin>>n; for(i=1;i<=n;i++) {cin>>x; put(x);} //输入的元素入堆,建立小根堆 for(i=1;i<n;i++) // n个数 合并n-1次 { x=get(); y=get(); //i=1 x=1,y=2 ans=3 3入堆 ans+=x+y; //i=2 x=3,y=9 ans=3+3+9=15 15入堆,结束循环 put(x+y); } cout<<ans<<endl; } int main() { work(); return 0; }