Sort---hdu5884(优先队列+二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5884
题意:有n个有序序列,每个序列有ai个元素,现在有一个程序每次可以归并最多k个序列,最终把所有的序列合并成一个,每次归并所需要的代价是所有序列的长度和;
现有一个代价界限T,就是总的代价不能超过T,求符合条件的最小的K;
当给定一个K的准确值时,我们可以每次选择最小的k个数进行合并;所以我们可以用优先队列来处理,但是由于范围比较大,可以优化一下,只让合并形成的序列进入优先队列,每次取数组和队列中较小的一个即可;
对于k可以用二分的方法来求,但是会发现当n=5,k=4的时候,当直接运用上面的做法,最后没有k个数,那么就不能保证单调性了,为了保证每次都是k个序列进行合并,我们可以运用补0的方法进行处理,这样就保证了二分的正确性;
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
using namespace std;
#define met(a, b) memset(a, b, sizeof(a))
#define N 100005
#define INF 0x3f3f3f3f
typedef long long LL; int M, n, a[N], sum[N]; bool Judge(int k)
{
int r = (n-k)%(k-), Index;
LL s;
if(r == )///如果已经满足每次都是k个数了,直接取数组的前k项即可;
{
s = sum[k];
Index = k+;
}
else///否则就先把前r+1个数进行合并;
{
s = sum[r+];
Index = r+;
}
priority_queue<LL>Q;
Q.push(s); while(!Q.empty() || Index <= n)
{
if(Index > n && Q.size() == ) break;///当只剩下队列中的一个数时,说明已经合并完成了; int cnt = ; LL part = ;
while(cnt<k && (!Q.empty() || Index<=n))
{
if(Index <=n && (Q.empty() || a[Index] <= Q.top()))
part += a[Index++];
else
{
part += Q.top();
Q.pop();
}
cnt++;
}
s += part;
if(s > M) break; Q.push(part);
}
return s<=M;
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
met(a, );
met(sum, ); scanf("%d %d", &n, &M); for(int i=; i<=n; i++)
scanf("%d", &a[i]); sort(a, a+n+);
for(int i=; i<=n; i++)
sum[i] = sum[i-] + a[i]; int L = , R = n, ans = ;
while(L <= R)
{
int Mid = (L+R)/;
if(Judge(Mid))
{
R = Mid - ;
ans = Mid;
}
else
L = Mid + ;
}
printf("%d\n", ans);
}
return ;
}
/*
5 15
0 0 0 0 0
*/
Sort---hdu5884(优先队列+二分)的更多相关文章
- Sort HDU5884(二分+多叉哈夫曼树)
HDU5884 Sort 题意:有n个序列要进行归并,每次归并的代价是两个序列的长度的和,要求最终的代价不能超过规定的T,求在此前提下一次能同时进行归并的序列的个数k. 思路:还是太单纯,看完题目一直 ...
- Sort HDU - 5884(优先队列+二分)
Sort Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- POJ 2010 Moo University - Financial Aid( 优先队列+二分查找)
POJ 2010 Moo University - Financial Aid 题目大意,从C头申请读书的牛中选出N头,这N头牛的需要的额外学费之和不能超过F,并且要使得这N头牛的中位数最大.若不存在 ...
- sort()和优先队列的总结
一.关于sort函数 sort()排序函数默认是从小到大, a={5,3,2,1,6 }; sort(a,a+n); //输出是1 2 3 5 6 这里如果要从到小排序,则有两种方式可以满足 (1) ...
- Sort(hdu5884)
Sort Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- sort排序与二分查找
#include<iostream> #include<vector> #include<algorithm> #include<string> usi ...
- 给小班讲stl 之 map、sort、优先队列
引子:最近老师让给小班讲课,讲stl,,但是我觉得就小班现在这水平根本讲不懂好不好,,,,
- Gym 101064 D Black Hills golden jewels (二分)
题目链接:http://codeforces.com/gym/101064/problem/D 问你两个数组合相加的第k大数是多少. 先sort数组,二分答案,然后判断其正确性(判断过程是枚举每个数然 ...
- 4 Values whose Sum is 0(二分)
4 Values whose Sum is 0 Time Limit: 15000MS Memory Limit: 228000K Total Submissions: 21370 Accep ...
随机推荐
- Vijos 1100 (区间DP)
题目链接: https://vijos.org/p/1100 题目大意:NOIP著名的加分二叉树.给出一棵树的中序遍历,加分规则左子树*右子树+根.空子树分数为1.问最大加分的树结构,输出树结构的先序 ...
- topcoder SRM 592 DIV2 LittleElephantAndBooks
#include <iostream> #include <vector> #include <algorithm> using namespace std; cl ...
- BZOJ2738: 矩阵乘法
Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Input 第一行两个数N,Q,表示矩阵大小和询问组数: 接下来N行N列一共N*N个数,表示这个矩阵: ...
- C# DateTime 日期加1天 减一天 加一月 减一月 等方法(转)
//今天 DateTime.Now.Date.ToShortDateString(); //昨天,就是今天的日期减一 DateTime.Now.AddDays(-1).ToShortDateStrin ...
- StereoBM::disp12MaxDiff Crash the Release
Initializing "cv::StereoBM bm.state->disp12MaxDiff" should be careful, inappropriate va ...
- Using pg_dump restore dump file on Odoo
pg_restore -C -d postgres db.dump
- DirSync: List of attributes that are synced by the Azure Active Directory Sync Tool
http://social.technet.microsoft.com/wiki/contents/articles/19901.dirsync-list-of-attributes-that-are ...
- $_ 与 $PSItem
PowerShell 3.0 中的$PSItem 此文章于2012年11月4日发表在PowershellPowershell小技巧并加以Powershell 3.0管道的标签 by Mooser Le ...
- OC学习笔记——类别(Category)
类别,有些程序员又称之为分类. 类别是一种为现有的类添加新方法的方式,尤其是为系统的做扩展的时候,不用继承系统类,可以直接为类添加新的方法.也可以覆盖系统类的方法. 如: @interface NSO ...
- Apache Spark源码走读之16 -- spark repl实现详解
欢迎转载,转载请注明出处,徽沪一郎. 概要 之所以对spark shell的内部实现产生兴趣全部缘于好奇代码的编译加载过程,scala是需要编译才能执行的语言,但提供的scala repl可以实现代码 ...