HDU 5884 Sort ——(K叉哈夫曼树)
这题真心比较奥义,先见这个人的博客:http://blog.csdn.net/libin66/article/details/52565484
补0的方法是使得其满足成为满K叉树,而其博客中所说的“所以当(n-1)%(k-1)!=0的时候,会出现归并不能最大化个数的情况,这样会影响二分的单调性”我作如下的解释:
至于为什么不加0,sum会变大呢?作如下的解释:因为有一次合并不是最大个数的话,与其让它在后面单独合并增加权值还不如在前面补0合并呢,毕竟我们在算k的时候sum越小越好嘛~
原先代码如下(WA):
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
using namespace std;
const int N = + ;
typedef long long ll; int n,lim;
int a[N]; bool can(int k)
{
if(k == ) return false;
queue<ll> Q1,Q2;
ll sum = ;
for(int i=;i<=n;i++) Q1.push((ll)a[i]);
while(Q1.size()+Q2.size() > )
{
if(Q1.size()+Q2.size() >= k)
{
ll temp = ;
for(int i=;i<=k;i++)
{
if(Q2.size()==)
{
temp += Q1.front();Q1.pop();
}
else if(Q1.size()==)
{
temp += Q2.front();Q2.pop();
}
else if(Q1.front()<=Q2.front())
{
temp += Q1.front();Q1.pop();
}
else
{
temp += Q2.front();Q2.pop();
}
}
sum += temp;
Q2.push(temp);
}
else
{
ll temp = ;
while(!Q1.empty())
{
temp += Q1.front();Q1.pop();
}
while(!Q2.empty())
{
temp += Q2.front();Q2.pop();
}
sum += temp;
}
}
return sum <= (ll)lim;
} int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&lim);
for(int i=;i<=n;i++) scanf("%d",a+i);
sort(a+,a++n);
int L = , R = n;
int ans = ;
while(L <= R)
{
//printf("!! %d %d\n",L,R);
int mid = L + R >> ;
if(can(mid))
{
ans = mid;
R = mid - ;
}
else L = mid + ;
}
printf("%d\n",ans);
}
return ;
} /*
6
6 120
10 10 10 10 10
*/
WA的代码
AC代码如下:
#include<iostream>
//#include<bits/stdc++.h>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<ctime>
#include<algorithm>
#include<cmath>
#include<vector>
#define showtime fprintf(stderr,"time = %.15f\n",clock() / (double)CLOCKS_PER_SEC)
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
typedef long long LL;
#define MP make_pair
#define PII pair<int,int>
#define PLI pair<long long ,int>
#define PFI pair<double,int>
#define PLL pair<ll,ll>
#define PB push_back
#define F first
#define S second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define debug cout<<"?????"<<endl;
//freopen("1005.in","r",stdin);
//freopen("data.out","w",stdout);
const int INF = 0x7f7f7f7f;
const double eps = 1e-;
const int M = + ;
const int N = + ;
const double PI = acos(-.);
const double E = 2.71828182845904523536;
const int MOD = ;
typedef vector<ll> Vec;
typedef vector<Vec> Mat;
int T,n,a[ + ];
ll m;
bool ok(int k){
queue<ll> q,p;
int t = (n-) % (k-);
// 每次减少k-1个数。一共要减少 (n-1) 个数。 还剩下几个数要和 0 一组了
if(t != ) for(int i = ; i < k - t - ; i ++) q.push();
for(int i = ; i < n ; i ++) q.push(a[i]); ll ans = ;
while(!q.empty() || !p.empty()){
ll tmp = ;
for(int i = ; i < k ; i ++){
if(!q.empty() && !p.empty()){
ll u = q.front() , v = p.front();
if(u < v) tmp += u , q.pop();
else tmp += v , p.pop();
}else if(!q.empty()){
ll u = q.front(); q.pop();
tmp += u;
}else if(!p.empty()){
ll v = p.front() ; p.pop();
tmp += v;
}else break;
}
ans += tmp;
if(q.empty() && p.empty()) break;
p.push(tmp);
}
return ans <= m;
}
void solve(){
int l = , r = n;
while(l < r){
int m = (l+r)>>;
if(ok(m)) r = m;
else l = m + ;
}
cout << l << endl;
}
int main(){
cin >> T;
while(T --){
cin >> n >> m;
for(int i = ; i < n ; i ++) scanf("%d",&a[i]);
sort(a,a+n);
solve();
}
return ;
}
AC代码
HDU 5884 Sort ——(K叉哈夫曼树)的更多相关文章
- 两个队列+k叉哈夫曼树 HDU 5884
// 两个队列+k叉哈夫曼树 HDU 5884 // camp题解: // 题意:nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过TT, ...
- 2016 年青岛网络赛---Sort(k叉哈夫曼)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5884 Problem Description Recently, Bob has just learn ...
- hdu5884 Sort(二分+k叉哈夫曼树)
题目链接:hdu5884 Sort 题意:n个有序序列的归并排序.每次可以选择不超过k个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问k最小是多少. 题解:先二分k,然后在k给 ...
- 【CF884D】Boxes And Balls k叉哈夫曼树
题目大意:给定一个大小为 N 的集合,每次可以从中挑出 2 个或 3 个数进行合并,合并的代价是几个数的权值和,求将这些数合并成 1 个的最小代价是多少. 引理:K 叉哈夫曼树需要保证 \((n-1) ...
- UOJ#130 【NOI2015】荷马史诗 K叉哈夫曼树
[NOI2015]荷马史诗 链接:http://uoj.ac/problem/130 因为不能有前缀关系,所以单词均为叶子节点,就是K叉哈夫曼树.第一问直接求解,第二问即第二关键字为树的高度. #in ...
- AcWing:149. 荷马史诗(哈夫曼编码 + k叉哈夫曼树)
追逐影子的人,自己就是影子. ——荷马 达达最近迷上了文学. 她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>. 但是由<奥德赛>和<伊 ...
- HDU 5884 Sort (二分+k叉哈夫曼树)
题意:n 个有序序列的归并排序.每次可以选择不超过 k 个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问 k最小是多少. 析:首先二分一下这个 k .然后在给定 k 的情况下, ...
- bzoj 4198 [ Noi 2015 ] 荷马史诗 —— 哈夫曼编码(k叉哈夫曼树)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4198 第一次写哈夫曼树!看了很多博客. 哈夫曼树 & 哈夫曼编码:https://w ...
- P2168 [NOI2015]荷马史诗 k叉哈夫曼树
思路:哈夫曼编码 提交:1次(参考题解) 题解:类似合并果子$QwQ$ 取出前$k$小(注意如果叶子结点不满的话要补全),合并起来再扔回堆里去. #include<cstdio> #inc ...
- BZOJ 4198: [Noi2015]荷马史诗 哈夫曼树 k叉哈夫曼树
https://www.lydsy.com/JudgeOnline/problem.php?id=4198 https://blog.csdn.net/chn_jz/article/details/7 ...
随机推荐
- asp.net 10 Cookie & Session
Cookie 1.什么是Cookie 一小段文本,明文的数据,关于网站相关的文本字符串数据.一个客户端状态保持机制~ 存储在客户端的浏览器内存里面或者磁盘(如果不指定过期时间,那么存储在客户端浏览器内 ...
- element-ui 表单自定义日期输入校验
methods: { validateDate(rule, value, callback){ if (value) { let timestamp = new Date(value).getTime ...
- Java数据结构浅析
程序 = 数据结构 + 算法 本文概述Java中常用的数据结构,并简述其使用场景 1. 数据结构的定义 数据结构是一种逻辑意义,指的是逻辑上的数据组织方式及相应的处理,与数据在磁盘的具体存储方式不完全 ...
- js动态的往表格中加入表单元素
效果如图: 这里我用的是layui的静态表格,其他框架也是一样的(只要你都表单元素要通过js进行渲染),我的需求是在表单中放了表格的元素,表格中还有表单的元素.表格中的行数据是js动态添加的,正常的添 ...
- 第十五届四川省省赛 SCU - 4444 Travel
给你一个一共由两种边的完全图 要求你求1到N的最短路 q队列为前沿队列(已探索过且最外围的点) p队列为未探索队列(未探索过的点) depth这个数组的用法并不是代表实际上这个点在第几层 而是防止死 ...
- Linux系统用户权限管理
Linux系统中三种基本权限 用户属主.用户属组及其它人权限 -rw-r--r-- 1 root root 762 11-11 20:34 a.out 文件类型 ls命令中的缩写 应用 一般文件 - ...
- 今日理解之js
JavaScript 是前端的一门编程语言(也是有逻辑) node.js 支持前端js代码 跑在后端服务器上 Js跟Java什么关系? Js跟Java半毛钱关系都没有!!! 原因是当初Java特别火 ...
- MySQL BinLog Server 搭建实战
一.MySQL Binlog server 介绍 MySQL Binlog Server: 它使用 mysqlbinlog 命令以 daemon 进程的方式模拟一个 slave 的 IO 线程与主库连 ...
- IDEA 使用LiveEdit插件
第一步: 第二步: 第三步: 第四步: 等待下载完成 第五步: 第六步: 第七步: 配置tomcat时注意选择chrome浏览器,并勾选右边的多选框 完成之后,就可以启动项目了,然后可以改变html代 ...
- 特征工程中的IV和WOE详解
1.IV的用途 IV的全称是Information Value,中文意思是信息价值,或者信息量. 我们在用逻辑回归.决策树等模型方法构建分类模型时,经常需要对自变量进行筛选.比如我们有200个候选自变 ...