[bzoj4198]荷马史诗

很容易想到哈夫曼树,容易扩展得到贪心:优先选最小的k个合并,堆维护即可
为了保证深度最小,可以加入深度权值,在权值相同时选择当前深度最小的即可
(注意:由于可能最后一次不足k个,那么显然可以将这些不足的放到最深的位置来减小答案,需要补上权值为0的点来保证每一次都有k个)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 struct ji{
 5     int d;
 6     ll val;
 7     bool operator < (const ji &k)const{
 8         return (val>k.val)||(val==k.val)&&(d>k.d);
 9     }
10 };
11 priority_queue<ji>q;
12 int n,k,x;
13 ll s,ans;
14 int main(){
15     scanf("%d%d",&n,&k);
16     for(int i=1;i<=n;i++){
17         scanf("%lld",&s);
18         q.push(ji{0,s});
19     }
20     while ((n-1)%(k-1)){
21         n++;
22         q.push(ji{0,0});
23     }
24     while (n>1){
25         x=s=0;
26         for(int i=1;i<=k;i++){
27             s+=q.top().val;
28             x=max(x,q.top().d);
29             q.pop();
30         }
31         ans+=s;
32         q.push(ji{x+1,s});
33         n-=k-1;
34     }
35     printf("%lld\n%d",ans,q.top().d);
36 }
View Code
posted @ 2019-12-11 16:43  PYWBKTDA  阅读(174)  评论(0编辑  收藏  举报