1 // 两个队列+k叉哈夫曼树 HDU 5884
 2 // camp题解:
 3 // 题意:nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过TT, 问kk最小是多少。
 4 // .
 5 // 题解:首先二分一下这个kk。然后在给定kk的情况下,这个代价其实就是kk叉的哈夫曼树问题。因此直接套用哈夫曼树的堆做法即可。复杂度O(nlog^2n)
 6 // ​,这样优化一下读入是可以卡过去的。
 7 // 然后主代码手表示,利用合并的单调性,可以去掉优先队列得到O(nlogn)的做法:先对所有数排序,另外一个队列维护合并后的值,取值时从两个序列前端取小的即可。
 8 // 昂:如果(n-1)%(k-1)≠0,要把最小的(n-1)%(k-1)+1个数先合并一下。
 9
10 #include <iostream>
11 #include <algorithm>
12 #include <cstring>
13 #include <cstdio>
14 #include <vector>
15 #include <cmath>
16 #include <map>
17 #include <queue>
18 using namespace std;
19 #define LL long long
20 typedef pair<int,int> pii;
21 const int inf = 0x3f3f3f3f;
22 const int MOD = 998244353;
23 const int N = 1e5+10;
24 const int maxx = 200010;
25 #define clc(a,b) memset(a,b,sizeof(a))
26 const double eps = 1e-8;
27 void fre() {freopen("in.txt","r",stdin);}
28 void freout() {freopen("out.txt","w",stdout);}
29 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
30
31 int a[N];
32 int n,m;
33 bool check(int k){
34     queue<LL>q1;
35     queue<LL>q2;
36     if((n-1)%(k-1)!=0){
37         for(int i=1;i<=k-1-(n-1)%(k-1);i++)
38             q1.push(0);
39     }
40     for(int i=1;i<=n;i++){
41         q1.push(a[i]);
42     }
43     LL sum=0;
44     while(1){
45         LL tem=0;
46         for(int i=1;i<=k;i++){
47             if(q1.size()==0&&q2.size()==0) break;
48             int a1,a2;
49             if(q1.size()==0){
50                 tem+=q2.front();
51                 q2.pop();
52                 continue;
53             }
54             if(q2.size()==0) {
55                tem+=q1.front();
56                q1.pop();
57                continue;
58             }
59             a1=q1.front();
60             a2=q2.front();
61             if(a1<a2) {tem+=a1;q1.pop();}
62             else {tem+=a2;q2.pop();}
63         }
64         sum+=tem;
65         if(q1.size()==0&&q2.size()==0) break;
66         q2.push(tem);
67     }
68     if(sum>m) return false;
69     else return true;
70 }
71
72 int main(){
73     // fre();
74     int T;
75     scanf("%d",&T);
76     while(T--){
77         scanf("%d%d",&n,&m);
78         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
79         sort(a+1,a+1+n);
80         int l=2,r=n;
81         while(l<r){
82             int mid=(l+r)>>1;
83             if(check(mid)) r=mid;
84             else l=mid+1;
85         }
86         printf("%d\n",r);
87     }
88     return 0;
89 }

转载于:https://www.cnblogs.com/ITUPC/p/5880773.html

两个队列+k叉哈夫曼树 HDU 5884相关推荐

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

    题干: Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task fr ...

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

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

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

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

  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. 哈夫曼树(Huffman树) 学习日记 + 例题(ch1701 bzoj4198)

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

  9. 优先级队列实现哈夫曼树的编码和译码

    //优先级队列实现的哈夫曼树的编码和译码 #include<iostream> #include<queue> #include<string> using nam ...

最新文章

  1. python2必须安装步骤_Python入门-第三方库的安装及环境配置(2)
  2. Python基础--1.2 变量循环基础介绍
  3. hexo d后 ERROR Deployer not found: git
  4. 同IP不同端口Session冲突问题
  5. 2017 百度杯丶二月场第一周WP
  6. Stringbuffer的线程安全是怎么实现的
  7. Ubuntu-显卡驱动-nvidia-smi报错:couldn‘t communicate with the NVIDIA driver
  8. linux下vmware的安装、物理分区使用及卸载
  9. 小程序流量主运营技巧
  10. 第六章第三十一题(金融应用:信用卡号的合法性验证)(Financial: credit card number validation)
  11. 21届本科大数据菜鸡:我是怎么在互联网寒冬拿到腾讯、华为、京东、美团、快手等大厂offer的?
  12. Windows update 注册表项
  13. 当你压力大到快崩溃时,不要跟任何人说,也不要觉得委屈
  14. 【编程题】【Scratch四级】2021.03 程序优化
  15. 计算机毕业后的打算英语作文,毕业后规划英语作文
  16. SVM-支持向量机理解(拉格朗日乘子法(Lagrange multiplier))
  17. 【日常】矩阵正态分布参数检验问题
  18. python中ord函数
  19. Python之CSV文件操作
  20. 双指针的应用,力扣977

热门文章

  1. 人的幸福感取决于什么
  2. 在.NET中excel导出方法汇总(收集)
  3. 测试一体机ASM failgroup的相关问题处理
  4. Cisco堆叠配置步骤+链路聚合实例
  5. 怎么安装Win10,硬盘安装Win10系统图文教程
  6. iptables的SNAT和DNAT应用
  7. ZEN CART 在LINUX系统下设置邮箱方法---用GMAIL设置,方法选择SMTPAUTH
  8. 技术QA:如何安装并启用BITS和WebDAV?
  9. Android App图片轮播效果的组件化
  10. 搞懂Java的反射机制