zoukankan      html  css  js  c++  java
  • 【BZOJ4198】【NOI2015】荷马史诗(贪心,Huffman树)

    【BZOJ4198】【NOI2015】荷马史诗(贪心,Huffman树)

    题面

    BZOJ
    洛谷

    题解

    合并果子都是不知道多久以前做过的了。现在才知道原来本质就是一棵哈夫曼树啊。
    这题我们仔细研究一下题目的意思。
    就是让你构造一个(K)叉树,所有的权值都放在叶子节点上,求权值乘深度和的最小值。
    如果(K=2),我们发现这就是合并果子。
    (K>2),那么不过就是合并果子加强版,把原来每次选择最小的两个换成选择最小的(K)个就好了。
    因为可能在最后一次选的时候选不满,所以提前补一些(0),进去让他能够选满就好了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    inline ll read()
    {
        RG ll x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >Q;
    ll ans;
    int n,K;
    int main()
    {
    	n=read();K=read();
    	for(int i=1;i<=n;++i)Q.push(make_pair(read(),0));
    	while((n-1)%(K-1)!=0)Q.push(make_pair(0,0)),++n;
    	while(Q.size()>=K)
    	{
    		pair<ll,int> u=make_pair(0,0),v;
    		for(int i=1;i<=K;++i)
    		{
    			v=Q.top();Q.pop();
    			u.first+=v.first;u.second=max(u.second,v.second+1);
    		}
    		ans+=u.first;Q.push(u);
    	}
    	printf("%lld
    %d
    ",ans,Q.top().second);
    	return 0;
    }
    
    
  • 相关阅读:
    Oracle视图,索引,序列
    Oracle的表创建和事务管理
    Oracle子查询和多表查询
    python实现二叉树
    python实现二分查找
    python实现各种排序算法
    flask邮件发送
    django之图片预览实现方法
    django ORM操作
    Django Form之select自动更新
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9251539.html
Copyright © 2011-2022 走看看