一、题目描述
有n(n≤5000)个数的集合S,每次可以从S中删除两个数,然后把它们的和放回集合,直到剩下一个数。每次操作的开销等于删除的两个数之和,求最小总开销。所有数均小于100000。
(紫书例题8-11)
二、算法说明
贪心,每次都取最小的两个数相加即可使每一步的开销最小,进而使总开销最小。
三、AC 代码(10 ms)
#include<cstdio>
#include<set>
#pragma warning(disable:4996)
using namespace std;
int main() {
unsigned n, a, r, r0; multiset<unsigned> s; multiset<unsigned>::iterator I;
for (;;) {
scanf("%u", &n); if (n == 0)return 0;
r = 0; s.clear();
for (unsigned i = 0; i < n; ++i) { scanf("%u", &a); s.emplace(a); }
for (unsigned i = 1; i < n; ++i) {
I = s.begin(); r0 = *I + *(++I); r += r0;
s.erase(s.begin()); s.erase(s.begin()); s.emplace(r0);
}
printf("%u\n", r);
}
}