首页 > 其他分享 >P2168 [NOI2015] 荷马史诗

P2168 [NOI2015] 荷马史诗

时间:2024-03-30 11:55:22浏览次数:19  
标签:队列 P2168 荷马史诗 ll 叶子 NOI2015 权值 节点

原题链接

题解

1.该题等价于构建一颗k叉树,每个叶子节点都有一个权值 \(leaf_i\) ,树的权值为 \(\sum_{1}^{n}leaf_i\) ,在使树的权值尽可能小的情况下,使最深的叶子节点的深度也尽可能小,即使数的高度尽可能小
这个叫做哈夫曼树

2.构建过程如下:每次从队列中取出 \(k\) 个节点,然后把他们合并成一个节点,在放回队列中。直至最后只剩下1个节点。
但是队列到最后可能剩下大于1,小于k个节点,也就是说,最高层的k叉树是不满的,这样显然不优,因为越高层的叶子节点对数的总权值贡献越小
解决方法是一开始往队列里加权值为0的叶子节点,这些叶子节点会优先布满最底层,然且不对树权值造成影响

code

#define ll long long
#include<bits/stdc++.h>
using namespace std;

inline void read(ll &x) {
	x = 0;
	ll flag = 1;
	char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')flag = -1;
        c = getchar();
    }
	while(c >= '0' && c <= '9') {
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	x *= flag;
}

inline void write(ll x)
{
    if(x < 0){
    	putchar('-');
		x = -x;
	}
    if(x > 9)
		write(x / 10);
    putchar(x % 10 + '0');
}

struct node
{
    ll val, layer;
    bool operator<(const node &b) const
    {
        if(b.val!=val) return b.val<val;
        return b.layer<layer;
    }
};

int main()
{
    ll n, k;
    read(n);
    read(k);
    priority_queue<node> q;

    for(ll i = 1; i <= n; i++)
    {
        ll x;
        read(x);
        q.push({x, 1});
    }

    while((q.size() - 1) % (k - 1) != 0)  q.push({0, 1});

    ll ans1 = 0, ans2 = 0;
    while(q.size() != 1)
    {
        ll sum = 0, height = 0;

        for(ll i = 1; i <= k; i++)
        {
            sum += q.top().val;
            height = max(height, q.top().layer);
            q.pop();
        }
        q.push({sum, height + 1});
        ans1 += sum;
        ans2 = max(ans2, height);
    }

    write(ans1);
    putchar('\n');
    write(ans2);
    return 0;
}

标签:队列,P2168,荷马史诗,ll,叶子,NOI2015,权值,节点
From: https://www.cnblogs.com/pure4knowledge/p/18105304

相关文章

  • 洛谷题单指南-集合-P1955 [NOI2015] 程序自动分析
    原题链接:https://www.luogu.com.cn/problem/P1955题意解读:要判断约数条件是否可以同时满足,主要是要判断不相等的情况。解题思路:对于相等的条件,直接进行集合合并即可;对于不相等的条件,判断两者是否属于同一个集合,如果形成矛盾,则条件不能成立。由于i,j的范围至10^9,定义并查集如果......
  • P3242 [HNOI2015] 接水果 抽象做法
    好吧好吧,自己做出来的第一道整体二分。省流:理解能力比较强的话直接拖到最后看算法流程吧。下面我们称输入时盘子的权值为“盘子的大小”,与文中使用的算法给盘子的赋权区分开。一堆询问第\(k_i\)小,考虑整体二分。先考虑外部过程。上整体二分板子,每次二分\(mid\),形象地把盘......
  • P2178 [NOI2015] 品酒大会
    题意简述定义后缀\(p,q\)是\(r\)相似的当且仅当\(\forall1\lei\ler,s_{p+i-1}=s_{q+i-1}\)。对于每一个\(0\ler<n\),求出:有多少对\(r\)相似的后缀。每个后缀有权值\(a_i\),求在所有\(r\)相似的后缀对\((p,q)\)中\(a_p\cdota_q\)的最大值。若不存在则答案为......
  • TJ -「HNOI2015」开店
    TJ-「HNOI2015」开店(洛谷)一,题意给你一棵\(n\)个节点的树,点有点权,边有边权,\(Q\)次询问每次让你求解点权在\(L\)到\(R\)之间的点到点\(u\)的距离和。(强制在线)数据范围:\(n\le1.5\times10^5,Q\le2\times10^5\)二,思路首先,我们先看弱化版,假设没有年龄的限制,看单个询问,设\(dis_i......
  • [NOI2015] 品酒大会
    独立过了一道NOI的题,开心~我的做法是后缀数组+单调栈+st表,并没有用到并查集点击查看代码#include<bits/stdc++.h>usingnamespacestd;strings;intsa[300005],rk[20][300005],r[300005],n,w,h[300005],p[25],z[300005],st0[20][300005],st1[20][300005],f[600005];lo......
  • P2178 [NOI2015] 品酒大会 题解
    P2178[NOI2015]品酒大会题解纪念一下第一道完全自己想出来的紫NOI题。思路由于r相似有单调性的性质,题目中也提示了这一点,考虑按\(height_i\)从大到小把所有相邻的\(sa\)数组内两个后缀合并,用并查集维护,发现第一问的答案就是\[\sum_{i是并查集的根}\binom{size_i}{2}......
  • P3243 [HNOI2015] 菜肴制作 题解
    前言今天考试考到这道题,挂惨了。题意有\(n\)道菜肴,编号为\(1\simn\)。有\(m\)个条件,形如\((i,j)\),表示菜肴\(i\)必须在菜肴\(j\)之前制作。需求出一个菜肴的制作顺序,满足:在满足所有限制的前提下,\(1\)号菜肴尽量优先制作。在满足所有限制,\(1\)号菜肴尽量优......
  • [NOI2015] 寿司晚宴
    P2150[NOI2015]寿司晚宴翻译一下,题目其实就是给你\(2-n\)这些数,从其中选出两个集合(可以为空),求使两个集合中的数两两互质的方案数。那么就相当于说两个集合中的数的质因数的集合不能有重合。先看前\(\%30\)的数据,\(n<=30\),里面的质因数不多,考虑状压\(DP\)。我们不妨设\(DP[i]......
  • P1955 [NOI2015] 程序自动分析
    P1955[NOI2015]程序自动分析基本思路考虑到了不等号的不可传递性,所以决定只开相等的并查集。然后突发奇想,觉得可以在找父亲的过程中判断是不是冲突。然而这样就不能路径压缩,显然超时。并且,根本没看清楚数据范围,实际上这题的数很大,裸开数组会爆炸。这是一开始的代码#inclu......
  • P2146 [NOI2015] 软件包管理器 题解
    [NOI2015]软件包管理器题目背景Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debi......