• LOJ#2132. 「NOI2015」荷马史诗


    $n leq 100000$个数字,放进$k$叉树里,一个点只能放一个数,使所有数字乘以各自深度这个值之和最小的同时,最大深度的数字最小。

    哈夫曼。这是我刚学OI那段时间看到的,感觉就是个很无聊的贪心,而且密码学我也不学深对哈夫曼的应用也了解不多,没想到出现在noi。

    原来的哈夫曼只需要每次拿k个最小的数出来,建一个他们共同的父亲并在一起,当作一个权值为他们权值之和的新点,用堆可以实现;由于$(n-1) mod (k-1)$不一定为0,需要补几个0点进去。相对于原来的哈夫曼,这里多了个深度限制,那只需要把堆里元素再记一下最大深度就可以了。

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 //#include<math.h>
     5 //#include<set>
     6 #include<queue>
     7 //#include<bitset>
     8 //#include<vector>
     9 #include<algorithm>
    10 #include<stdlib.h>
    11 using namespace std;
    12 
    13 #define LL long long
    14 int qread()
    15 {
    16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
    17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
    18 }
    19 
    20 //Pay attention to '-' , LL and double of qread!!!!
    21 
    22 int n,K;
    23 #define maxn 200011
    24 struct qnode
    25 {
    26     LL v; int dep;
    27     bool operator > (const qnode &b) const {return v>b.v || (v==b.v && dep>b.dep);}
    28 };
    29 priority_queue<qnode,vector<qnode>,greater<qnode> > q;
    30 
    31 int main()
    32 {
    33     n=qread(); K=qread(); LL v;
    34     for (int i=1;i<=n;i++) {scanf("%lld",&v); q.push((qnode){v,0});}
    35     if ((n-1)%(K-1)) for (int i=1,to=(K-1)-(n-1)%(K-1);i<=to;i++) q.push((qnode){0,0}),n++;
    36     LL ans=0;
    37     for (int i=1,to=(n-1)/(K-1);i<=to;i++)
    38     {
    39         LL nv=0; int nd=0;
    40         for (int j=1;j<=K;j++) nv+=q.top().v,nd=max(nd,q.top().dep),q.pop();
    41         ans+=nv; q.push((qnode){nv,nd+1});
    42     }
    43     printf("%lld
    %d
    ",ans,q.top().dep);
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    webpack基础
    LeetCode232. 用栈实现队列做题笔记
    mysql 时间加减一个月
    leetcode 1381. 设计一个支持增量操作的栈 思路与算法
    LeetCode 141. 环形链表 做题笔记
    leetcode 707. 设计链表 做题笔记
    leetcode 876. 链表的中间结点 做题笔记
    leetcode 143. 重排链表 做题笔记
    leetcode 1365. 有多少小于当前数字的数字 做题笔记
    LeetCode1360. 日期之间隔几天 做题笔记
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9288151.html
Copyright © 2020-2023  润新知