HDU 5884 Sort(二分答案+计算WPL的技巧)
Sort
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2377 Accepted Submission(s): 610
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.
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).
这题容易想到二分答案K来做,但是仅仅是这样用手写的堆的也是超时的,加了输入外挂也没卡过去(T_T),显然这样的复杂度是NLogN * LogN ,数据一大就T了
然后膜了一下别人的方法:由于每一次拿k-1个数和1个数合并,因此会剩下(n-1)%(k-1)个数,因此用(k-1)-(n-1)%(k-1)个0与(n-1)%(k-1)个剩下的数凑成k-1个数,这样一来最后就一定一次性完全合并,因此先向qa输入(k-1)-(n-1)%(k-1)个0,再把先把原数组排序再放到qa中,qa用来保存未经过合并的数字,qb用来维护合并过程中的数字,这样K叉哈夫曼树的WPL计算方法就成了每一次从这两个队列中取出队头最小的一个元素,取K个,这样就是一次合并,那么合并的复杂度就成了O(N),总复杂度变成了N * LogN 这里算是学到了一个计算WPL的技巧。
代码:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 100010;
struct Que
{
LL arr[N << 1];
int l, r;
void init()
{
l = r = 0;
}
void push(const LL &val)
{
arr[r++] = val;
}
void pop()
{
++l;
}
inline LL front()
{
return arr[l];
}
inline bool empty()
{
return l == r;
}
};
Que qa, qb;
LL arr[N];
int n;
LL T; bool check(const int &k)
{
qa.init();
qb.init();
int res = (n - 1) % (k - 1);
if (res)
{
res = (k - 1) - res;
while (res--)
qa.push(0LL);
}
for (int i = 1; i <= n; ++i)
qa.push(arr[i]); LL sum = 0LL;
while ((!qa.empty()) || (!qb.empty()))
{
LL temp = 0LL;
for (int i = 0; i < k; ++i)
{
if (qa.empty() && qb.empty())
break;
if (!qa.empty() && !qb.empty())
{
if (qa.front() < qb.front())
{
temp += qa.front();
qa.pop();
}
else
{
temp += qb.front();
qb.pop();
}
}
else if (!qa.empty())
{
temp += qa.front();
qa.pop();
}
else if (!qb.empty())
{
temp += qb.front();
qb.pop();
}
}
sum += temp;
if (qa.empty() && qb.empty())
break;
qb.push(temp);
}
return sum <= T;
}
int main(void)
{
int tcase, i;
scanf("%d", &tcase);
while (tcase--)
{
scanf("%d%I64d", &n, &T);
for (i = 1; i <= n; ++i)
scanf("%I64d", arr + i);
sort(arr + 1, arr + 1 + n);
int L = 2, R = n;
int k = 1;
while (L <= R)
{
int mid = (L + R) >> 1;
if (check(mid))
{
k = mid;
R = mid - 1;
}
else
L = mid + 1;
}
printf("%d\n", k);
}
return 0;
}
HDU 5884 Sort(二分答案+计算WPL的技巧)的更多相关文章
- HDU 5884 Sort (二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5884 nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的 ...
- HDU 5884 Sort (二分+k叉哈夫曼树)
题意:n 个有序序列的归并排序.每次可以选择不超过 k 个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问 k最小是多少. 析:首先二分一下这个 k .然后在给定 k 的情况下, ...
- HDU - 5884 Sort (二分答案+贪心)
有n个数字,你需要把这n个数字合成一个数字,每次只能把k个数字合并成一个,花费为这k个数字的和. 给一个最大花费,问不超过这个最大花费的情况下,k的最小值. Sample Input 1 5 25 1 ...
- Sort HDU - 5884(优先队列+二分)
Sort Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- U - Inviting Friends HDU - 3244(二分答案 + 完全背包)
U - Inviting Friends HDU - 3244 You want to hold a birthday party, inviting as many friends as possi ...
- HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)
好题 题意:给你n<=100000个数,每个数范围[0,1000],然后给你一个最大的代价T,每次最多合并k个数成为一个数,代价为k个数的总和.问最后合成1个数的总代价不大于T的最小k 题解:我 ...
- HDU 5884 Sort(二分+优先队列)
http://acm.hdu.edu.cn/showproblem.php?pid=5884 题意:有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和.现在另外一个屌丝要 ...
- 【最优K叉树】hdu 5884 Sort
http://acm.hdu.edu.cn/showproblem.php?pid=5884 参考:https://www.cnblogs.com/jhz033/p/5879452.html [题意] ...
- noiac64 sort (二分答案)
首先如果L=1,那就可以直接用一个优先队列来做 但它并不是1 所以要换个做法 假设我们已经知道第L的数是x,第R的数是y 那其实就只需要找到[x+1,y+1]这一段,然后再加上一定数量的x和y就是答案 ...
随机推荐
- mongodb索引 全文索引
全文索引,也叫文本索引,平时,我们百度的搜索,比如api文档的搜索,这种全局的索引就可以使用全文索引实现 全文索引:对字符串与字符串数组创建全文可搜索对索引 使用情况:比如有一个数据集合,存储了用户的 ...
- findsmb - 列出在子网上响应SMB名称查询的主机信息
SYNOPSIS 总览 findsmb [子网广播地址] 描述 此perl脚本是Samba组件的一部分. findsmb是个用于打印出关于子网中响应SMB名字查询请求的主机信息的perl脚本.实际上它 ...
- Softmax回归(Softmax Regression
多分类问题 在一个多分类问题中,因变量y有k个取值,即.例如在邮件分类问题中,我们要把邮件分为垃圾邮件.个人邮件.工作邮件3类,目标值y是一个有3个取值的离散值.这是一个多分类问题,二分类模型在这里不 ...
- java基础编程——获取栈中的最小元素
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). 题目代码 /** * Created by YuKai Fan on 2018/9 ...
- shell脚本:变量,文件判断,逻辑运算等纪要
shell脚本中的变量定义,引用各有不同的方式,除此之外,很常用的有文件属性判断,逻辑运算,数值运算等,下面记录一下它们的属性作用 变量 shell变量的定义分为两种:一种是直接赋值定义,另一种是嵌套 ...
- linux普通文件权限和系统目录权限的实践及结论
测试结论:linux普通文件的读.写.执行权限说明 1.可读r:表示具有读取\阅读文件内容的权限 2.可写w:表示具有新增.修改文件内容的权限 1)如果没有r配合,那么vi编辑文件会提示无法编辑(但可 ...
- 权限组件(12):自动发现项目中有别名的URL
自动发现项目中所有有别名的URL,效果如下: customer_list {'name': 'customer_list', 'url': '/customer/list/'} customer_ad ...
- A1009 Product of Polynomials (25)(25 分)
A1009 Product of Polynomials (25)(25 分) This time, you are supposed to find A*B where A and B are tw ...
- ACM模板
#include <iostream> //万能头文件#include<bits/stdc++.h> 方便时用 #include <algorithm> #incl ...
- 51nod 1105 二分答案法标准题目
二分答案法例题,用于练习二分答案的基本思想非常合适,包括了思维方式转换的内容(以前我们所做的一直是利用二分法求得数组元素对应指针之类,但是现在是直接对答案进行枚举). 思路是:首先对输入数组进行排序, ...