题目链接:http://codevs.cn/problem/1063/
分析
这道题考查的是堆,我们首先取出两个最小的数,合并然后再加入到堆中,并调整堆结构,因为取的是最小的数,所以采用小根堆,这道题也可以用优先队列来做,下面采用的是手动模拟堆的方式。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 10000 + 10
int heap[N],cnt;
int n,ans;
//模拟小根堆
void push(int x)//向上调整
{
heap[++cnt] = x;//先插入到尾部,然后再调整
int i = cnt;
while(i > 1 && heap[i] < heap[i >> 1]) swap(heap[i],heap[i >> 1]),i >>= 1;
}
void pop()
{
heap[1] = heap[cnt--];
int i = 1,j = 2;//向下调整
while(j <= cnt) {
if(j < cnt && heap[j + 1] < heap[j]) j |= 1;//j += 1
if(heap[i] > heap[j]) {
swap(heap[i],heap[j]);
i = j,j <<= 1;
} else break;
}
}
int main()
{
scanf("%d",&n);
int x;
for(int i = 0; i < n; i++) {
scanf("%d",&x);
push(x);
}
int t;
while(--n) {
t = heap[1];pop();
t += heap[1];pop();
ans += t;
push(t);
}
printf("%d\n",ans);
return 0;
}