Sort(hdu5884)

Sort

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1038    Accepted Submission(s): 231

Problem Description

Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from Alice.
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.

Input

The first line of input contains an integer t0, the number of test cases. t0 test cases follow.
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).

Output

For each test cases, output the smallest k.

Sample Input

1
5 25
1 2 3 4 5

Sample Output

3

思路:二分+哈夫曼;

首先二分枚举k,然后关键就是check的时候,首先看一组数据:12345,当k为3的时候,按照如果我们取的话会得到21,然后再看k=4,我们的设想肯定是递减的,但是,如果我们开始就取4个的答案为25,所以这样二分就不行,但是是我们的取法不对,我们应该保证后面的大的数字 竟量只取1次,那么最后k-1个数肯定被一次加完,不会有剩余,那么N个数如果从开始能选k个,那么剩下的肯定要是k-1的倍数,那么当剩下的不是k-1的倍数,我们要在前面添加0,个数就是k-1-(N-1)%(k-1);这样就可以保证最优,也就单调了。

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 #include<iostream>
  5 #include<queue>
  6 #include<stdlib.h>
  7 #include<math.h>
  8 #include<set>
  9 using namespace std;
 10 typedef long long LL;
 11 queue<int>que1;
 12 queue<int>que2;
 13 LL ans[100005];
 14 bool check(int mid,int N,LL T);
 15 int main(void)
 16 {
 17     int n;
 18     scanf("%d",&n);
 19     while(n--)
 20     {
 21         int N;
 22         LL T;
 23         scanf("%d %lld",&N,&T);
 24         for(int i = 0; i < N; i++)
 25         {
 26             scanf("%lld",&ans[i]);
 27         }
 28         sort(ans,ans+N);
 29         int id = 1;
 30         int l = 2;
 31         int r = N;
 32         while(l<=r)
 33         {
 34             int mid = (l+r)/2;
 35             if(check(mid,N,T))
 36             {
 37                 r = mid-1;
 38                 id = mid;
 39             }
 40             else l = mid+1;
 41         }
 42         printf("%d\n",id);
 43     }
 44     return 0;
 45 }
 46 bool check(int mid,int N,LL T)
 47 {
 48     LL ask = 0;
 49     while(!que1.empty())
 50     {
 51         que1.pop();
 52     }
 53     while(!que2.empty())
 54     {
 55         que2.pop();
 56     }
 57     int x = (N-1)%(mid - 1);
 58     if(x!=0)
 59     {
 60         x = (mid-1-x)%(mid-1);
 61         while(x)
 62         {
 63             que1.push(0);
 64             x--;
 65         }
 66     }
 67     for(int i = 0; i < N ; i++)
 68     {
 69         que1.push(ans[i]);
 70         ask-=ans[i];
 71     }
 72     while(true)
 73     {
 74         LL sum = 0;
 75         int c = mid;
 76         while(c)
 77         {
 78             int flag = 0;
 79             if(!que1.empty()&&!que2.empty())
 80             {
 81                 int t = que1.front();
 82                 int tt = que2.front();
 83                 if(t<=tt)
 84                 {
 85                     que1.pop();
 86                 }
 87                 else
 88                 {
 89                     t = tt;
 90                     que2.pop();
 91                 }
 92                 sum+=t;
 93                 c--;
 94                 flag = 1;
 95             }
 96             else if(!que1.empty())
 97             {
 98                 int t = que1.front();
 99                 que1.pop();
100                 sum+=t;
101                 c--;
102                 flag = 1;
103             }
104             else if(!que2.empty())
105             {
106                 int t = que2.front();
107                 que2.pop();
108                 sum+=t;
109                 c--;
110                 flag = 1;
111             }
112             if(!flag)
113                 break;
114         }
115         que2.push(sum);
116         ask += sum;
117         if(c>0)break;
118     }
119     if(ask > T)
120         return false;
121     else return true;
122 }
时间: 2024-10-12 23:40:51

Sort(hdu5884)的相关文章

hdu5884 Sort(二分+k叉哈夫曼树)

题目链接:hdu5884 Sort 题意:n个有序序列的归并排序.每次可以选择不超过k个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问k最小是多少. 题解:先二分k,然后在k给定的情况下,构造k叉哈夫曼树.O(nlogn)的做法:先对所有数排序,另外一个队列维护合并后的值,取值时从两个序列前端取小的即可. 注:如果(n-1)%(k-1)!=0,那么就要增加(k-1-(n-1)%(k-1))个权值为0的叶子节点作虚拟点. 1 #include<cstdio> 2 #inc

hdu5884 Sort

//--------------------------------------------------------------- /*---贪心策略+二分+队列 -----将原数组排序,然后每次取k个较小的数合并,将合并的结果保存在一个队列中,继续取出k个数(队列和数组中)... -----但是会出现一个问题当(n-1)%(k-1)!=0时,这样最后剩下的数个数小于k,这会导致序列非严格递减.于是可以先将 -----前(n-1)%(k-1)+1个数合并结果放入队列中,剩下的恰好可以每次合并k个

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

Redis学习之Sort Set详解

本文和大家分享的主要是Redis中Sort Set相关内容,一起来看看吧,希望对大家学习redis有所帮助. 游戏服务器需要做一个排行榜实时更新,如果沿用传统的方法,一般是通过后端的定时任务去跑数据来生成排行榜数据,这种方法一方面无法满足产品对功能实时性的要求,另一方面也一定程度上消耗服务器端有限的资源.如果从每次数据库读取数据并进行排名(使用Mysql的sort关键字进行排序),在关卡数据量的级数大时是一种效率低的方法.在查阅大量资料后,发现了Redis中的有序集合(Sort Set). Re

75. Sort Colors

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. Here, we will use the integers 0, 1, and 2 to represent the color red, white, and bl

[BZOJ1552][Cerc2007]robotic sort

试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开的正整数P1,P2,P3-Pn,Pi表示第i次操作前第i小的物品所在的位置. 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品). 输入示例 6 3 4 5 1 6 2 输出示例 4 6 4 5 6 6 数据规模及约定 见"输入" 题解 暴力

PROC SORT

PROC SORT DATA=输入数据集 <OUT=输出数据集><选项>; BY 关键变量; RUN; PROC SORT 语法如上,其中在尖括号中的可以不出现,也不会报错. 选项中常用的有两种NODUPKEY和NOUNIQUEKEY. 功能可以由字面意思帮助记忆,NO-没有,DUP-重复,KEY-关键变量,,,合起来就是数据集中指定的关键变量不重复, 其功能也一样,,去除重复的关键变量,这里的关键变量就是指跟在关键字BY后面的变量:还有一个对应的DUPOUT=选项用来输出被该(N

PAT甲题题解-1101. Quick Sort (25)-大水题

快速排序有一个特点,就是在排序过程中,我们会从序列找一个pivot,它前面的都小于它,它后面的都大于它.题目给你n个数的序列,让你找出适合这个序列的pivot有多少个并且输出来. 大水题,正循环和倒着循环一次,统计出代码中的minnum和maxnum即可,注意最后一定要输出'\n',不然第三个测试会显示PE,格式错误. #include <iostream> #include <cstdio> #include <algorithm> #include <map&

八大排序算法之三选择排序—简单选择排序(Simple Selection Sort)

基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止. 简单选择排序的示例: 操作方法: 第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换: 第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换: 以此类推..... 第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与