http://acm.hdu.edu.cn/showproblem.php?pid=5884

参考:https://www.cnblogs.com/jhz033/p/5879452.html

【题意】

n个有序序列的归并排序.每次可以选择不超过k个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问k最小是多少。

【思路】

k越大,代价越小,二分k,check k

对于每个k,问题转化为n个结点的最优k叉树,用堆做时间复杂度为O(nlogn),再加上二分总复杂度是O(nlogn^2)

然后T了。。。听说加输入挂可以卡过去

正解是这样的:

原数组排序,预处理时间复杂度O(nlogn)

然后求最优k叉树,用一个队列维护合并后的值,而不需要加入原来的堆里重排序(利用新加入的内结点本身的单调性),每次时间复杂度为O(n)

O(nlogn)+O(logn)*O(n),所以最后时间复杂度是O(nlogn)

n个结点不一定能构成最优k叉树,需要补 k-1-((n-1)%(k-1))个权为0的虚结点。

 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
int n;
ll t;
const int maxn=1e5+;
ll a[maxn];
bool judge(int mid){
int cnt=(n-)/(mid-);
queue<ll> Q;
if((n-)%(mid-)!=){
cnt++;
for(int i=;i<(mid--(n-)%(mid-));i++){
Q.push();
}
}
ll ans=;
int l=;
while(cnt--){
ll tmp=;
for(int i=;i<mid;i++){
if(!Q.empty()&&(l>=n||Q.front()<=a[l])){
tmp+=Q.front();
Q.pop();
}else{
tmp+=a[l++];
}
}
ans+=tmp;
Q.push(tmp);
}
if(ans<=t) return true;
return false;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%lld",&n,&t);
for(int i=;i<n;i++){
scanf("%lld",&a[i]);
}
sort(a,a+n);
int l=,r=n;
while(l<=r){
int mid=(l+r)>>;
if(judge(mid)){
r=mid-;
}else{
l=mid+;
}
}
printf("%d\n",l);
}
return ;
}
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
int n;
ll t;
const int maxn=1e5+;
ll a[maxn];
bool judge(int mid){
queue<ll> Q1,Q2;
for(int i=;i<n;i++) Q1.push(a[i]);
if((n-)%(mid-)!=){
for(int i=;i<(mid--(n-)%(mid-));i++){
Q2.push();
}
}
ll ans=;
while(Q1.size()+Q2.size()>=mid){
ll tmp=;
for(int i=;i<mid;i++){
if(Q1.empty()&&!Q2.empty()){
tmp+=Q2.front();
Q2.pop();
}else if(Q2.empty()&&!Q1.empty()){
tmp+=Q1.front();
Q1.pop();
}else if(!Q1.empty()&&!Q2.empty()){
if(Q1.front()<=Q2.front()){
tmp+=Q1.front();
Q1.pop();
}else{
tmp+=Q2.front();
Q2.pop();
}
}
}
// cout<<tmp<<endl;
ans+=tmp;
Q2.push(tmp);
}
if(ans<=t) return true;
return false;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%lld",&n,&t);
for(int i=;i<n;i++){
scanf("%lld",&a[i]);
}
sort(a,a+n);
int l=,r=n;
while(l<=r){
int mid=(l+r)>>;
if(judge(mid)){
r=mid-;
}else{
l=mid+;
}
}
printf("%d\n",l);
}
return ;
}

【最优K叉树】hdu 5884 Sort的更多相关文章

  1. HDU 5884 Sort ——(K叉哈夫曼树)

    这题真心比较奥义,先见这个人的博客:http://blog.csdn.net/libin66/article/details/52565484 补0的方法是使得其满足成为满K叉树,而其博客中所说的“所 ...

  2. HDU 5884 Sort(二分答案+计算WPL的技巧)

    Sort Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  3. HDU 5884 Sort (二分+k叉哈夫曼树)

    题意:n 个有序序列的归并排序.每次可以选择不超过 k 个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问 k最小是多少. 析:首先二分一下这个 k .然后在给定 k 的情况下, ...

  4. HDU 5884 Sort (二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5884 nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的 ...

  5. HDU 5884 Sort(二分+优先队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=5884 题意:有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和.现在另外一个屌丝要 ...

  6. HDU 5884 Sort

    二分,验证. 二分$k$,然后进行验证.有一个地方需要注意一下:如果$n$个数,每次合并$k$个,最后一次不能合$k$个,那么一开始需要补$0$之后再合并才是最优的.合并的时候用优先队列合并时间复杂度 ...

  7. HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)

    好题 题意:给你n<=100000个数,每个数范围[0,1000],然后给你一个最大的代价T,每次最多合并k个数成为一个数,代价为k个数的总和.问最后合成1个数的总代价不大于T的最小k 题解:我 ...

  8. HDU - 5884 Sort (二分答案+贪心)

    有n个数字,你需要把这n个数字合成一个数字,每次只能把k个数字合并成一个,花费为这k个数字的和. 给一个最大花费,问不超过这个最大花费的情况下,k的最小值. Sample Input 1 5 25 1 ...

  9. 贪心(哈夫曼树):HDU 5884 sort

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2QAAAKACAIAAAB8KCy/AAAgAElEQVR4nOy9a5Adx3UmWL+kHxuekU ...

随机推荐

  1. 【数据库-MySQL on Azure】如何使用 MySQL EntityFramework 组件处理 MYSQL PaaS DB

    MySQL Database on Azure 是 Azure 平台上推出的 MySQL 云数据库服务,通过全面兼容 MySQL 协议,为用户提供了一个全托管的性能稳定.可快速部署.高可用.高安全性的 ...

  2. K-means、KNN学习笔记

    1.K-means:聚类算法,无监督 输入:k, data[n]; (1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1]; (2) 对于data[0]….dat ...

  3. windows定时任务小注

    static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static vo ...

  4. WPF中退出时显示是否保存数据提示

    一.通过窗体中的按钮实现退出时数据保存提示 Xaml: <Grid> <TextBlock HorizontalAlignment="Left" Margin=& ...

  5. nuxt 头部引入js文件 第一次进入页面不加载js文件的解决方法

    head () { return { title: '', meta: [ { hid: 'description', name: 'description', content: '' } ], sc ...

  6. Hopfield 网络(上)

    讲的什么 这部分主要对 Hopfield 网络作一大概的介绍.写了其模型结构.能量函数和网络的动作方式.主要参考了网上搜到的一些相关 PPT.   概述 早在 1982 年,Hopfield 发表的文 ...

  7. selenium-介绍和安装

    前戏 相信大家对web自动化selenium都不陌生,是一个web自动化框架,我在第一家公司的时候,产品是两个星期一个版本,每一次发布测试都要进行回归测试,也就是大家说的点点点,后来我就想,能不能做成 ...

  8. No-12.函数进阶

    函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...

  9. Bootstrap历练实例:导航内下拉菜单的用法

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  10. python安装mysql-connector出错

    windows 7环境 1.进入命令行执行以下命令: C:\Users\Administrator>pip install mysql-connector 注:安装下载较慢,直接失败,改用VPN ...