题干:

Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from Alice. 
Alice will give Bob NN sorted sequences, and the ii-th sequence includes aiai elements. Bob need to merge all of these sequences. He can write a program, which can merge no more than kk 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 TT cost. So Bob wants to know the smallest kk to make the program complete in time.

Input

The first line of input contains an integer t0t0, the number of test cases. t0t0 test cases follow. 
For each test case, the first line consists two integers N (2≤N≤100000)N (2≤N≤100000) and T (∑Ni=1ai<T<231)T (∑i=1Nai<T<231). 
In the next line there are NN integers a1,a2,a3,...,aN(∀i,0≤ai≤1000)a1,a2,a3,...,aN(∀i,0≤ai≤1000).

Output

For each test cases, output the smallest kk.

Sample Input

1
5 25
1 2 3 4 5

Sample Output

3

题目大意:

有n个数,每个数有个值,现在你可以选择每次K个数合并,合并的消耗为这K个数的权值和,问在合并为只有1个数的时候,总消耗不超过T的情况下,最小的K是多少

解题报告:

首先能想到的做法,二分一个K,然后check的时候按照标准k叉哈夫曼树的做法,搞个优先队列,别忘补0(通过n%(k-1)==1这个判断条件不断n++),但是这个做法是nlognlogn的。现在考虑优化:

首先如果是2叉哈夫曼树:

可以设两个数组,一个存放排序后的原数据,一个存放每次相加后的值。对于取之也有几种分析:

1.全部来源于a,此时q为空或者q的队头的元素比a的前两个元素都小.

2.全部来源于b,此时a为空或者a的队头的元素比b的前两个元素都小.

3.a和b中各取一个.

对于k叉:

就一个一个的取,一共取k次,每次取的时候就在两个数组中选一个小的就行了

AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#define mod (1000000007)
using namespace std;
typedef long long ll;
int a[200010];
int c[200010];
int b[200010];
int T;
int cal(int n,int k) {int i=1;int b1=0,cnt=0;int x=0;int ans=0;int add=0,y=k;if(k!=2) {while((n+add)%(k-1)!=1) add++;}for(int j=n; j>=1; j--) c[j+add]=a[j];for(int j=add; j>=1; j--) c[j]=0;n+=add;while(true) {int x=0;int ad=0;while((i<=n||b1<cnt)&&x<k) {if(i>n) {ad+=b[b1];ans+=b[b1];b1++;} else if(b1>=cnt) {ad+=c[i];ans+=c[i];i++;} else {if(c[i]<b[b1]) {ad+=c[i];ans+=c[i];i++;} else {ad+=b[b1];ans+=b[b1];b1++;}}x++;}if(i>n&&b1>=cnt) {break;}b[cnt++]=ad;}return ans;
}
int main() {int t;cin>>t;while(t--) {int n;scanf("%d%d",&n,&T);for(int i=1; i<=n; i++) scanf("%d",&a[i]);sort(a+1,a+1+n);int l=2,r=n;int ans;while(l<=r) {int mid=(l+r)/2;if(cal(n,mid)<=T) r=mid-1, ans=mid;else l=mid+1;}printf("%d\n",ans);}return 0;
}

【HDU - 5884】Sort(k叉哈夫曼树,优化tricks,两个队列代替优先队列)相关推荐

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

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

  2. K叉哈夫曼树构造方法 O(N)

    带权路径:是树中所有的叶结点的权值乘上其到根结点的路径长度. 哈夫曼树就是带权路径最小的树. 有n个数(即n个叶子节点),构造k叉(k>=2)哈夫曼树的方法: 构造哈夫曼树,其实就是不停的&qu ...

  3. 哈夫曼树+K叉哈夫曼树

    目录 基本概念 构造方法 证明 代码 k叉哈夫曼树 例题 基本概念 问题:给定n个权值,作为n个叶结点,构造一棵二叉树,而这棵树的特点是,有n个叶节点,叶节点的值为给定的权值.而内部节点的值为子树的权 ...

  4. 荷马史诗【k叉哈夫曼树】

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

  5. 【BZOJ4198】荷马史诗,贪心之k叉哈夫曼树

    传送门 思路: 很早以前听说过这个题 据说是一个很强的贪心(?) 然后一上来就往贪心上去想--(其实一开始知道算法不是很好,因为你不会走弯路了) 发现这玩意好像是个合并果子的模型-- 也不知道是怎么转 ...

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

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

  7. Sort HDU5884(二分+多叉哈夫曼树)

    HDU5884 Sort 题意:有n个序列要进行归并,每次归并的代价是两个序列的长度的和,要求最终的代价不能超过规定的T,求在此前提下一次能同时进行归并的序列的个数k. 思路:还是太单纯,看完题目一直 ...

  8. 哈夫曼树的带权路径长度(C++优先队列实现)

    哈夫曼树 题目描述 哈夫曼树,第一行输入一个数n,表示叶结点的个数.需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和的最小值. ...

  9. 哈夫曼树(Huffman树) 学习日记 + 例题(ch1701 bzoj4198)

    哈夫曼树: 一棵包含n个叶子节点的k叉树,其中第i个叶子节点带有权值w[i], l[i]为该点到根节点的距离,求所有叶子节点的w[i]*l[i]之和的最小值. 二叉哈夫曼树的求解: 对于二叉哈夫曼树的 ...

最新文章

  1. 如何使用其他文件中定义的类Python
  2. MySQL 中主键的几种表设计组合的实际应用效果
  3. 使用Guava CharMatcher和Apache Commons Lang StringUtils确定字符串中字符或整数的存在
  4. 满足多个条件的JAVA语句_关于Java:关于具有多个条件的If语句的快速问题
  5. Bootstrap3 工具提示插件的方法
  6. 什么样的流_量最容易变现?
  7. 20191202_k-中心聚类算法和k-mean算法Python实现
  8. Hownet在NLP领域内是什么样的地位?
  9. 《通信原理》复习笔记6----第六章数字基带传输系统(重中之重点+难上加难点)
  10. kuka机器人程序是c语言吗,KUKA机器人示教器编程问题讲解——KUKA机器人
  11. 酒店标识的要求不同其设计也不同
  12. 全球各大运营商代码。方便国外卡的朋友修改运营商显示
  13. 批处理系统、分时系统、实时操作系统的特点和比较
  14. 怎么登陆和退出MySQL
  15. 有梦为马,追寻梦想——基层优秀教育工作者佟鑫海
  16. python 爬取亚马逊评论_用Python爬取了三大相亲软件评论区,结果...
  17. HttpClient使用不当,服务挂了!是时候系统学习一下了
  18. 关于servlet生命周期
  19. Python 写对联
  20. Linux系统通过iso镜像作为源,安装gedit命令

热门文章

  1. NYOJ88(数论)
  2. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第29篇]什么是UF-CMA数字签名的定义?
  3. HDU odd-even number 数位dp
  4. 服务器网盘系统怎么装,云服务器上怎么安装操作系统
  5. 对代理商的评价怎么写_简历中的自我评价怎么写才能更吸引人?
  6. python代做在哪找靠谱_比较靠谱的资产评估师考试去哪找
  7. Linux内核参数传递Tag
  8. 计算机突然从桌面消失了,电脑桌面突然什么都没有了,怎么处理
  9. java 邮件模板_Spring Boot 2发送邮件手把手图文教程
  10. python内置函数分类_Python 69个内置函数分类总结