2016青岛网络赛 Sort
Sort
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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.
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).
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个合并;
注意如果(n-1)%(k-1)!=0,则要先把(n-1)%(k-1)+1个合并,以保证最优合并;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #define rep(i,m,n) for(i=m;i<=n;i++) #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define Lson L, mid, rt<<1 #define Rson mid+1, R, rt<<1|1 const int maxn=1e5+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;} int n,m,k,t,a[maxn]; bool check(int k) { int i,j,ans=0,now,cnt; queue<int>p,q; rep(i,1,n)p.push(a[i]); if((j=(n-1)%(k-1))!=0) { now=0; rep(i,1,j+1)now+=p.front(),p.pop(); ans+=now,q.push(now); } while(p.size()+q.size()>1) { cnt=now=0; while(cnt<k) { if(!p.empty()&&(q.empty()||p.front()<=q.front()))now+=p.front(),p.pop(); if(!q.empty()&&(p.empty()||q.front()<=p.front()))now+=q.front(),q.pop(); cnt++; } ans+=now,q.push(now); } return ans<=m; } int main() { int i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); rep(i,1,n)scanf("%d",&a[i]); sort(a+1,a+n+1); int l=2,r=n,ans; while(l<=r) { int mid=l+r>>1; if(check(mid))ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); } //system("Pause"); return 0; }