HDU 5884 青岛网络赛(二分加维护队列)
2016-09-17 21:15
330 查看
Sort
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 689 Accepted Submission(s): 134
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
题目大意:
nn个有序序列的归并排序.每次可以选择不超过
kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过
TT,
问
kk最小是多少。
思路:先对所有的数排序,二分查找k,之后再将合并之后的数字存入一个队列之中。每次取数组和队列中较小的数。这样就可以,不过有个需要注意
如果
(n-1) \%(k-1) \neq 0(n−1)%(k−1)≠0,要把最小的
(n-1)\%(k-1)+1(n−1)%(k−1)+1个数先合并一下
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <queue> using namespace std; long long num[111111]; int main() { int t; scanf("%d", &t); while (t--) { long long n,T; queue<long long> q; scanf("%lld%lld",&n,&T); for (int i = 0 ; i < n ; i++ ) { scanf("%lld",&num[i]); } sort(num,num+n); while (!q.empty()) { q.pop(); } int l = 2 , r = n; while (l <r) { long long sum = 0; int mid = (l + r) / 2; //printf("%d\n",mid); long long temp = 0; int all = 0; if ((n - 1) % (mid - 1) != 0) { for (int i = 0 ; i < ((n - 1) % (mid - 1)) + 1 ; i++ ) { temp += num[i]; } all = ((n - 1) % (mid - 1)) + 1; sum += temp; q.push(temp); } temp = 0; int cou = 0; while (!q.empty() || all < n) { if (q.empty()) { sum += num[all]; temp += num[all]; all++; cou++; } else { if ( all < n) { if (q.front() >= num[all]) { sum += num[all]; temp += num[all]; all++; cou++; } else { sum += q.front(); temp += q.front(); q.pop(); cou++; } } else { sum += q.front(); temp += q.front(); q.pop(); cou++; } } if ( cou == mid ) { if ( all < n || !q.empty()) q.push(temp); else break; temp = 0; cou = 0; } //printf("%lld %d\n",sum , all); } while (!q.empty()) { q.pop(); } if (sum > T) { l = mid + 1; } else { r = mid; } } printf("%d\n",l); } return 0; }
相关文章推荐
- hdu 5548 sort 2016青岛区域赛网络赛 二分+队列优化
- HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)
- hdu 5884 Sort 二分+哈夫曼树(解决不单调问题) 队列优化
- hdu 5884 Sort(二分+哈夫曼树(队列))
- HDU 6215 2017Brute Force Sorting 青岛网络赛 队列加链表模拟
- hdu 5884 Sort 二分+K哈夫曼树(解决不单调问题) 队列优化
- HDU 5884-Sort(队列+二分)
- 2017青岛ACM网络赛解题报告——hdu 6216 二分查找
- HDU 5884 Sort(二分加双队列优化)
- HDU 5878 I Count Two Three (打表+二分查找) -2016 ICPC 青岛赛区网络赛
- hdu 3717 二分+队列维护
- hdu 5884 Sort 二分 + K叉哈夫曼树 两个队列
- hdu_5884_Sort(二分+单调队列)
- hdu 5884 二分+队列
- HDU 5884 Sort(二分+单调队列)
- HDU 5884 Sort (二分+双队列)
- HDU 6215 2017Brute Force Sorting 青岛网络赛 队列加链表模拟
- hdu 5884 Sort 2016ACM/ICPC青岛赛区网络赛1007
- HDU 5884 Sort -2016 ICPC 青岛赛区网络赛
- 【2017青岛网络赛】1004 hdu 6209 The Intersection 二分