• 题解
  • 荷马史诗题解

  • @ 2024-9-6 20:49:27

题意:根据分析,此题与合并果子类似,但是是合并k堆果子,且要求树的高度尽可能小。

解析: 需要考虑两个与合并果子不同的情况:

第一、有可能最后会没有k堆取的情况,解决办法如下: 首先,能取k堆,会满足: nm(k1)=1=>n1=m(k1)n - m(k-1) = 1 => n - 1 = m(k-1),因为mm是整数,所以要满足(n - 1) % (k - 1) == 0, 如果不为00,则需要补齐,发现题目的权值都是正数,所以,我们可以补权值为0的结点,此时不影响结果。

第二、要求最小高度,那么考虑合并时候,有没有可能优化。如果最小的k堆果子唯一,则无需优化;如果最小的k堆果子不唯一,则选择前k个高度最小的,此时新生成的结点高度为最小。

其他思路与合并果子类似,只不过用结构体分别存权值和高度。

代码如下:时间复杂度O(nklogn)O(nklogn)

#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 条评论

目前还没有评论...