hdu 5884 Sort 2016ACM/ICPC青岛赛区网络赛1007
2016-09-18 00:44
369 查看
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
然后就是k叉的哈夫曼树
我们可以直接把原数列sort一下
然后用两个数列维护。每次计算结果放第二个数列中,再每次比较两格数列的头指针的数哪个小,累加
因为数组可以在二分外面直接排序,这样就比直接用堆做少了一个log
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct number
{
long long x;
bool operator <(number y) const
{
return x>y.x;
}
}b[100001];
int a[100001];
int n;
long long t;
priority_queue<number> Q;
long long q1[1000001],q2[1000001];
inline bool check(int limit)
{
int i,j;
int l1=1,r1=0,l2=1,r2=0;
int m=limit-1;
int tt=n;
while(tt%m!=1&&m!=1)
{
r1++;
q1[r1]=0;
tt++;
}
for(i=1;i<=n;i++)
{
r1++;
q1[r1]=a[i];
}
long long sum=0,ans=0;
/* for(i=1;i<=((n-1)-1)%m+1;i++)
{ vv
l1++;
sum+=q1[l1];
}*/
ans+=sum;
// r2++;
// q2[r2]=sum;
for(i=1;i<=tt/m;i++)
{
sum=0;
int sx=0;
while(sx<limit&&l1<=r1&&l2<=r2)
{
if(q1[l1]<=q2[l2])
{
sum+=q1[l1];
l1++;
}
else
{
sum+=q2[l2];
l2++;
}
sx++;
}
if(sx<limit)
{
if(l1<=r1)
{
while(sx<limit)
{
sum+=q1[l1];
l1++;
sx++;
}
}
else
{
while(sx<limit)
{
sum+=q2[l2];
l2++;
sx++;
}
}
}
r2++;
q2[r2]=sum;
ans+=sum;
}
return ans<=t;
}
int main()
{
int T;
scanf("%d",&T);
while(T>0)
{
T--;
scanf("%d%I64d",&n,&t);
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(i=1;i<=n;i++)
b[i].x=a[i];
int l=2,r=n;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))
r=mid-1;
else
l=mid+1;
}
printf("%d\n",l);
}
return 0;
}
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
然后就是k叉的哈夫曼树
我们可以直接把原数列sort一下
然后用两个数列维护。每次计算结果放第二个数列中,再每次比较两格数列的头指针的数哪个小,累加
因为数组可以在二分外面直接排序,这样就比直接用堆做少了一个log
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct number
{
long long x;
bool operator <(number y) const
{
return x>y.x;
}
}b[100001];
int a[100001];
int n;
long long t;
priority_queue<number> Q;
long long q1[1000001],q2[1000001];
inline bool check(int limit)
{
int i,j;
int l1=1,r1=0,l2=1,r2=0;
int m=limit-1;
int tt=n;
while(tt%m!=1&&m!=1)
{
r1++;
q1[r1]=0;
tt++;
}
for(i=1;i<=n;i++)
{
r1++;
q1[r1]=a[i];
}
long long sum=0,ans=0;
/* for(i=1;i<=((n-1)-1)%m+1;i++)
{ vv
l1++;
sum+=q1[l1];
}*/
ans+=sum;
// r2++;
// q2[r2]=sum;
for(i=1;i<=tt/m;i++)
{
sum=0;
int sx=0;
while(sx<limit&&l1<=r1&&l2<=r2)
{
if(q1[l1]<=q2[l2])
{
sum+=q1[l1];
l1++;
}
else
{
sum+=q2[l2];
l2++;
}
sx++;
}
if(sx<limit)
{
if(l1<=r1)
{
while(sx<limit)
{
sum+=q1[l1];
l1++;
sx++;
}
}
else
{
while(sx<limit)
{
sum+=q2[l2];
l2++;
sx++;
}
}
}
r2++;
q2[r2]=sum;
ans+=sum;
}
return ans<=t;
}
int main()
{
int T;
scanf("%d",&T);
while(T>0)
{
T--;
scanf("%d%I64d",&n,&t);
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(i=1;i<=n;i++)
b[i].x=a[i];
int l=2,r=n;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))
r=mid-1;
else
l=mid+1;
}
printf("%d\n",l);
}
return 0;
}
相关文章推荐
- HDU 5884 Sort -2016 ICPC 青岛赛区网络赛
- hdu 5889 Barricade 2016ACM/ICPC青岛赛区网络赛1011
- hdu 5882 Balanced Game 2016ACM/ICPC青岛赛区网络赛1005
- HDU 5884 Sort 2016 ACM/ICPC Asia Regional Qingdao Online 1007
- hdu 5881 Tea 2016ACM/ICPC青岛赛区网络赛1004
- hdu 5879 Cure 2016ACM/ICPC青岛赛区网络赛1002
- hdu 5898 odd-even number 2016ACM/ICPC沈阳赛区网络赛1007
- hdu 5886 Tower Defence 2016ACM/ICPC青岛赛区网络赛1009
- hdu 5883 The Best Path 2016ACM/ICPC青岛赛区网络赛1006
- hdu 5878 I Count Two Three 2016ACM/ICPC青岛赛区网络赛1001
- HDU 5879 - Cure【2016 ACM 区域赛青岛赛区网络赛】
- HDU - 6214 Smallest Minimum Cut (2017 ACM-ICPC 亚洲区 (青岛赛区) 网络赛 1009)
- HDU - 6213 Chinese Zodiac (2017 ACM-ICPC 亚洲区 (青岛赛区) 网络赛 1008)
- 2016 ACM/ICPC 青岛赛区网络赛 XM Reserves
- HDU 5884 Sort 2016 ACM/ICPC Asia Regional Qingdao Online
- HDU 5878 I Count Two Three (打表+二分查找) -2016 ICPC 青岛赛区网络赛
- 2016 ACM/ICPC Asia Regional Qingdao Online hdu 5884 Sort (智商+队列)★
- hdu 5875 Function 2016ACM/ICPC大连赛区网络赛1008
- HDU 5881 Tea -2016 ICPC 青岛赛区网络赛
- hdu 5869 Different GCD Subarray Query 2016ACM/ICPC大连赛区网络赛1002