如题意所述,每个箱子都是相同的,所以分螺丝的过程中螺丝的位置并不重要,只需要将 $\sum a$ 的螺丝分成 $n$ 堆,第 $i$ 堆 $a_i$ 个即可,每次可以将一堆分成 $2$ 或 $3$ 堆。
每次分成 $2$ 或 $3$ 堆很难维护,考虑逆操作,即每次将 $2$ 堆或 $3$ 堆合并成一堆,每次代价为这几堆石子的个数总和,于是便成了哈夫曼板子题,可参见 荷马史诗。
代码:
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;
const int N = 100010;
int main()
{
int n, m = 3;
cin >> n;
priority_queue<PLI, vector<PLI>, greater<PLI>> heap;
for (int i = 0; i < n; i ++ )
{
LL w;
cin >> w;
heap.push({w, 0});
}
while ((n - 1) % (m - 1))
{
heap.push({0ll, 0});
n ++ ;
}
LL res = 0;
while (heap.size() > 1)
{
LL sum = 0;
int depth = 0;
for (int i = 0; i < m; i ++ )
{
sum += heap.top().first;
depth = max(depth, heap.top().second);
heap.pop();
}
res += sum;
heap.push({sum, depth + 1});
}
cout << res << endl;
return 0;
}
这里说一下,由于作者 @_mayiwei 码风不太好看于是在题解中使用了我的代码。
orz
为什么不能直接两个两个叶子进行合并?
太妙了