题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5884

Problem Description
Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from Alice.
Alice will give Bob N sorted sequences, and the i-th sequence includes ai elements. Bob need to merge all of these sequences. He can write a program, which can merge no more than k sequences in one time. The cost of a merging operation is the sum of the length of these sequences. Unfortunately, Alice allows this program to use no more than T cost. So Bob wants to know the smallest k to make the program complete in time.
 
Input
The first line of input contains an integer t0, the number of test cases. t0 test cases follow.
For each test case, the first line consists two integers N (2≤N≤100000) and T (∑Ni=1ai<T<231).
In the next line there are N integers a1,a2,a3,...,aN(∀i,0≤ai≤1000).
 
Output
For each test cases, output the smallest k.
 
Sample Input
1
5 25
1 2 3 4 5
 
Sample Output
3
 
Source
 
 
Recommend
wange2014   |   We have carefully selected several similar problems for you:  5891 5890 5889 5887 5886 
 
题意:to组数据,每次输入N,T,然后输入N个数,进行合并操作,将其中k个数合并为一个数后,代价为这k个数的和,并将这个和放入剩余的数列中,一直合并下去......最后合并为一个数,要求总的代价不超过T,求最小的k值;
 
思路:k叉哈夫曼树,很明显k值在2~N之间,而且k越大总的代价越小,那么利用这个性质我们可以对k值进行二分查找,我开始时想的用优先队列做,但超时了......我们可以对数组先从小到大排序,然后利用一个队列装合并得到的数,每次取数组和队列中较小的数,注意用一个变量pos记录数组取完数后的下一个位置,队列中取完数后要删除这个数,为什么可以这样呢? 因为每次合并得到的数一定小于等于上次合并得到的数,所以最小数一是 数组pos位置和队列首中的较小者。另外,这些数的个数不一定满足k个k个的合并,所以要先合并不足的几个数,什么时候不满足呢,(N-1)%(k-1)!=0 时;
 
代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <queue>
#include <cmath>
#include <string.h>
using namespace std;
int N;
long long T;
long long a[]; int calc(int k)
{
queue<long long>q;
int pos=;
long long sum=;
if((N-)%(k-)!=&&N>k) ///如果不能k个k个合并到底,则先合并筹不足k个的;
{
pos=(N-)%(k-)+;
for(int i=;i<pos;i++) sum+=a[i];
q.push(sum);
}
while()
{
long long sum2=;
for(int i=; i<k; i++)
{
if(!q.empty())
{
if(pos<N&&q.front()>a[pos])
{
sum2+=a[pos];
sum+=a[pos];
pos++;
}
else
{
sum2+=q.front();
sum+=q.front();
q.pop();
}
}
else if(pos<N)
{
sum2+=a[pos];
sum+=a[pos];
pos++;
}
else goto endw;
}
if(sum>T) return ;
if(pos<N||!q.empty())
q.push(sum2);
}
endw:;
if(sum<=T) return ;
else return ;
} int main()
{
int to;
scanf("%d",&to);
while(to--)
{
scanf("%d%lld",&N,&T);
for(int i=; i<N; i++)
scanf("%lld",&a[i]);
sort(a,a+N);
int l=,r=N,mid;
while(l<=r)
{
mid=(l+r)>>;
int f=calc(mid);
if(f==) l=mid+;
else r=mid-;
}
printf("%d\n",l);
}
return ;
}

2016 年青岛网络赛---Sort(k叉哈夫曼)的更多相关文章

  1. hdu5884 Sort(二分+k叉哈夫曼树)

    题目链接:hdu5884 Sort 题意:n个有序序列的归并排序.每次可以选择不超过k个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问k最小是多少. 题解:先二分k,然后在k给 ...

  2. 两个队列+k叉哈夫曼树 HDU 5884

    // 两个队列+k叉哈夫曼树 HDU 5884 // camp题解: // 题意:nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过TT, ...

  3. 【CF884D】Boxes And Balls k叉哈夫曼树

    题目大意:给定一个大小为 N 的集合,每次可以从中挑出 2 个或 3 个数进行合并,合并的代价是几个数的权值和,求将这些数合并成 1 个的最小代价是多少. 引理:K 叉哈夫曼树需要保证 \((n-1) ...

  4. UOJ#130 【NOI2015】荷马史诗 K叉哈夫曼树

    [NOI2015]荷马史诗 链接:http://uoj.ac/problem/130 因为不能有前缀关系,所以单词均为叶子节点,就是K叉哈夫曼树.第一问直接求解,第二问即第二关键字为树的高度. #in ...

  5. AcWing:149. 荷马史诗(哈夫曼编码 + k叉哈夫曼树)

    追逐影子的人,自己就是影子. ——荷马 达达最近迷上了文学. 她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>. 但是由<奥德赛>和<伊 ...

  6. HDU 5884 Sort (二分+k叉哈夫曼树)

    题意:n 个有序序列的归并排序.每次可以选择不超过 k 个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问 k最小是多少. 析:首先二分一下这个 k .然后在给定 k 的情况下, ...

  7. BZOJ 4198: [Noi2015]荷马史诗 哈夫曼树 k叉哈夫曼树

    https://www.lydsy.com/JudgeOnline/problem.php?id=4198 https://blog.csdn.net/chn_jz/article/details/7 ...

  8. bzoj 4198 [ Noi 2015 ] 荷马史诗 —— 哈夫曼编码(k叉哈夫曼树)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4198 第一次写哈夫曼树!看了很多博客. 哈夫曼树 & 哈夫曼编码:https://w ...

  9. P2168 [NOI2015]荷马史诗 k叉哈夫曼树

    思路:哈夫曼编码 提交:1次(参考题解) 题解:类似合并果子$QwQ$ 取出前$k$小(注意如果叶子结点不满的话要补全),合并起来再扔回堆里去. #include<cstdio> #inc ...

随机推荐

  1. Atitit 数据库事务实现原理

    Atitit 数据库事务实现原理   1.1. 自己在程序中实现事务操作. 如果只是需要事务的话,你自己给mongo操作加上事务功能就可以啦..数据库事务只不过是他自己实现了而已..如果数据库不支持事 ...

  2. java学习笔记--this 关键字的理解

    彻底理解this 关键字的含义 this关键字再java里面是一个我认为非常不好理解的概念,:)也许是太笨的原因 this 关键字的含义:可为以调用了其方法的那个对象生成相应的句柄. 怎么理解这段话呢 ...

  3. 发现一个百度的密码。。。记最近一段时间的php感想

    请看图. 突然想看一下百度的cookie. 最近百度一年真是多攒多难,我一直挺百度啊.百度文化就是程序员文化,但是收到中国其他文化的侵蚀,不得不变, 任何人重构系统,都会有大概百分三十左右的性能提升. ...

  4. 每天一个linux命令(44):top命令

    top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.下面详细介绍它的使用方法.top是一个动态显示过程,即可以通过用户按键来不断刷新 ...

  5. 如何使用ITEXTSHARP将HTML代码字符串写进PDF

    原文 如何使用ITEXTSHARP将HTML代码字符串写进PDF itextsharp包括一个简单的类,可以用来根据html代码或字符串创建pdf文件.使用此类,你可以使用短短几行代码,就将 HTML ...

  6. POJ1014 解题报告(DFS)

    题目在此:http://poj.org/problem?id=1014 要看清题意呢,题中要求输入的是价值分别为1,2,3,4,5,6的大理石的个数,而不是6块价值为输入数字的大理石!选这个题主要想练 ...

  7. 【WP 8.1开发】自定义(RAW)通知的使用

    继续前面的话题,还是推送通知.上一篇文章中遗留了RAW通知的推送没有给各位演示,特特地留到现在,不为别的,只为这个RAW通知有点意思,玩起来会比较有意思.官方文档将RAW通知译为“原始通知”,这里还是 ...

  8. Object.create

    var emptyObject = Object.create(null); var emptyObject = Object.create(null); var emptyObject = {}; ...

  9. CSS3入门之转换

    CSS3入门之转换 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impor ...

  10. 拓扑排序(一)之 C语言详解

    本章介绍图的拓扑排序.和以往一样,本文会先对拓扑排序的理论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑 ...