hdu5884 Sort【k叉哈夫曼树】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5884
新学到的:

①判断是不是满的哈夫曼树:

为什么要判断是不是满的哈夫曼树喃?
因为满的哈夫曼树才是最优的
比如1 2 3 4,最多合并3个,并取最小的三个数1 2 3 就合并成6,然后再合并6 4

而是先合并1 2,成3,再合并3 3 4这样代价最小

k叉哈夫曼树:<mark>多余的节点=(N-1)%(k-1)</mark>
如果多余的节点计算出来是0,那就是满的
怎么理解喃?

看这个图,3叉哈夫曼树,每个只有最后一个是3个,而其他每层都只有(3-1)个,所以这个就很容易明白了

所以如果给的不是满的哈夫曼树,就阔以有两种方法变成满的:
①:把(多余的+1)个合并成1个
②:缺少的用0来补充

而我的代码是选择补充0,因为要方便补充0,因此才从大到小倒着来的

②不用优先队列

这道题因为有个二分就已经有个log了,所以用优先队列再来个log就有点卡时间了,因此这个优化在这道题中体现得淋漓尽致,我是先做的hdu1053练习的,我写得理解

#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=2e5+5;
const int MOD=1e9+7;
LL a[maxn];
LL N,SUM;
queue<LL>que;
LL f(int k)
{
    LL res=0;
    while(!que.empty())que.pop();
    int now=N;
    if((N-1)%(k-1)!=0)
	{
		int tp=(N-1)%(k-1);//表示多余的 
		now+=(k-(tp+1));//加0的个数 
	}
    while(now+que.size()>=k)
    {
        LL tp=0;
        for(int i=1;i<=k;i++)
        {
            if(que.empty() || a[now]<=que.front())tp+=a[now--];//就是这里我now变成0了,但是我a[0]=0是个很小的数,所以就进去了,因此把a[0]=inf就行了 
            else if(now<1 || que.front()<=a[now])
            {
                tp+=que.front();
                que.pop();
            }
        }
        que.push(tp);
        res+=tp;
    }
    return res;
}
int main()
{ 
    int T;
    cin>>T;
    while(T--)
    {
        memset(a,0,sizeof a);
        a[0]=1e9;//原来是now变成0的时候,a[0]=0最小,所以把他赋值成无穷大 
        cin>>N>>SUM;
        for(int i=1;i<=N;i++)scanf("%lld",a+i);
        sort(a+1,a+1+N,greater<int>());//方便加0的个数,所以倒起来 
        LL L=2,R=N,mid;
        while(L<=R)
        {
            mid=L+R>>1;
            LL tp=f(mid);
            if(tp>SUM)L=mid+1;
            else R=mid-1;
        }
        LL ans=min(R+10,N);
        while(f(ans-1)<=SUM)ans--;//二分没学好,所以二分出来的答案再来枚举 
        printf("%lld\n",ans);
    }
}
全部评论

相关推荐

个人背景:学院二本计科专业&nbsp;大二开始实习个人经历:安克创新&nbsp;、理想汽车、字节跳动碎碎念:我做事只有三分钟热度。看到进了大厂的同学,我会羡慕,也会跟着努力上进;但遇到好看的小说,我又会放下手头的事沉迷其中,之前的坚持也就中断了。我有些自卑,总觉得自己学历和外貌都不够好。之前偶然在网上受到关注,我就喜欢上了上网,因为这里有很多人认可我。但我也很在意别人的评价,偶尔看到嘲讽的言论,会触发我的自卑情绪,让我感到愤怒。有时候我会强硬地回怼,有时候又会懦弱地选择无视。我也有虚荣心。不管是拿到安克、理想还是字节的机会,我在分享的时候都会带着这份心思。我会特意强调自己学历不好,是为了衬托出过程的艰难,以此显得自己更厉害。我知道,人往往会炫耀自己缺少的东西,来掩盖内心的空洞。我总想着走捷径,不太喜欢踏踏实实地做事。找实习的时候,我花了更多时间在研究面试技巧上,而不是提升专业能力。我会反复听面试录音分析技巧,看面试教程学习怎么和不同的面试官沟通,还会每天自言自语练习语言表达,同学都觉得我有点奇怪。我的实习生涯里,侥幸和运气占了很大一部分。我总在想,如果有一天我失去了这份幸运,这些特质可能会让我一蹶不振。ps:&nbsp;很多人会问我学习路线和经验&nbsp;但是就像我上面说的&nbsp;我的实习过程靠的很多是关键节点的运气&nbsp;技术上面我可能不如很多人&nbsp;&nbsp;所以请大家理性求助和理性参考我的回答&nbsp;附上我的投递记录
我的offer在哪里...:从去年看到现在,飞升哥就是榜样
我的求职进度条
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务