- 题解
荷马史诗题解
- @ 2024-9-6 20:49:27
题意:根据分析,此题与合并果子类似,但是是合并k堆果子,且要求树的高度尽可能小。
解析: 需要考虑两个与合并果子不同的情况:
第一、有可能最后会没有k堆取的情况,解决办法如下:
首先,能取k堆,会满足: ,因为是整数,所以要满足(n - 1) % (k - 1) == 0, 如果不为,则需要补齐,发现题目的权值都是正数,所以,我们可以补权值为0的结点,此时不影响结果。
第二、要求最小高度,那么考虑合并时候,有没有可能优化。如果最小的k堆果子唯一,则无需优化;如果最小的k堆果子不唯一,则选择前k个高度最小的,此时新生成的结点高度为最小。
其他思路与合并果子类似,只不过用结构体分别存权值和高度。
代码如下:时间复杂度
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI; //first是w,second 是高度
const int N = 1e5 + 20;
int n, m;
//pair会以第一个参数先排,再以第二个参数排
priority_queue<PLI, vector<PLI>, greater<PLI> > heap;
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++)
{
LL w;
cin >> w;
heap.push({w, 0});
}
while((n - 1) % (m - 1)) {
heap.push({(LL)0, 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; //sum是求合并m堆果子的代价
depth = max(depth, heap.top().second);
heap.pop();
}
res += sum;
heap.push({sum, depth + 1});
}
cout << res << endl << heap.top().second << endl;
}
0 条评论
目前还没有评论...