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就是答案 ...
随机推荐
- css布局:块级元素的居中
一.定宽: 1.定位居中(absolute) 方法一: html: <div class="main"></main> css: .main{ width: ...
- 03_14_final关键字
03_14_final关键字 1. Final关键字 final的变量的值不能够被改变 final的成员变量 final的局部变量(形参) final的方法不能够被重写 final的类不能够被继承
- PHP数据库扩展 - PDO操作
PDO操作 PDO操作 描述:odp是php对数据库操作统一化的操作 语法:$pdo = new PDO("DB名:host=主机名;dbname=DB名","DB账号& ...
- GNU汇编 函数调用的例子
.text .global _start _start: mov r1,#2 cmp r1,#1 bl func1 @bl能保存下一条指令的位置到lr寄存器里面,b不能 mov r1, # ...
- 【JS】JS实现时间戳转换成普通时间
var time = 1514457627; alert(getDate(time)); function getDate(tm){ var tt=new Date(parseInt(tm) * 10 ...
- Yii 2.x html 代码压缩
<?php namespace Pangu\web; use yii\base\Component; /** * html格式响应内容格式化 * @author zhouzhian * */ c ...
- 使用python3下载网易云音乐歌单歌曲,附源代码
""" 用selenium+PhantomJS配合,不需要进行逆向工程 python 3下的selenium不能默认安装,需要指定版本2.48.0 "" ...
- POJ 3414 BFS 输出过程
Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17456 Accepted: 7407 Special J ...
- [Noip2016]换教室(期望+DP)
Description 题目链接:Luogu Solution 这题结合了DP和概率与期望,其实只要稍微知道什么是期望就可以了, 状态的构造很关键,\(F[i][j][0/1]\)表示已经到第\(i\ ...
- 笔记-python-standard library-9.6 random
笔记-python-standard library-9.6 random 1. random source code:Lib/random.py 1.1. functions for ...