题目链接
http://noi-test.zzstep.com/contest/0x10%E3%80%8C%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E3%80%8D%E4%BE%8B%E9%A2%98/1701%20%E5%90%88%E5%B9%B6%E6%9E%9C%E5%AD%90
分析
显然先合并重量小的果子更优,建堆初始放入所有果子的重量,每次取出重量最小的两个,累加答案,并将其和放入堆中。
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
inline int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return num;
}
const int maxn = 1e4 + 5;
struct Heap {
int h[maxn], tot;
Heap() {
memset(h, 0, sizeof(h));
tot = 0;
}
void up(int p) {
while (p > 1) {
if (h[p] < h[p / 2]) swap(h[p], h[p / 2]), p /= 2;
else break;
}
}
void down(int p) {
while (2 * p <= tot) {
int q = 2 * p;
if (q + 1 <= tot && h[q + 1] < h[q]) ++q;
if (h[q] < h[p]) swap(h[q], h[p]), p = q;
else break;
}
}
void insert(int x) {
h[++tot] = x;
up(tot);
}
int top() {
return h[1];
}
void remove(int p = 1) {
h[p] = h[tot--];
up(p), down(p);
}
} h;
int main() {
int n = read(), a, b, ans = 0;
for (int i = 1; i <= n; ++i) h.insert(read());
while (h.tot > 1) {
a = h.top(), h.remove();
b = h.top(), h.remove();
ans += a + b;
h.insert(a + b);
}
printf("%d", ans);
return 0;
}