ACM-ICPC 2016 Qingdao Preliminary Contest G. Sort

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 (2N100000) and T (Ni=1ai<T<231).
In the next line there are N integers a1,a2,a3,...,aN(i,0ai1000).
 


Output
For each test cases, output the smallest  k.
 


Sample Input
1 5 25 1 2 3 4 5
 


Sample Output
3
 
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <string>
 7 #include <deque>
 8 #include <queue>
 9 using namespace std;
10 #define  ll long long 
11 #define  N 100009
12 #define  gep(i,a,b)  for(int  i=a;i<=b;i++)
13 #define  gepp(i,a,b) for(int  i=a;i>=b;i--)
14 #define  gep1(i,a,b)  for(ll i=a;i<=b;i++)
15 #define  gepp1(i,a,b) for(ll i=a;i>=b;i--)    
16 #define  mem(a,b)  memset(a,b,sizeof(a))
17 int n,m,t;
18 int sum[N],a[N];
19 priority_queue<int,vector<int>,greater<int> >que;
20 bool check(int k){
21     while(!que.empty())  que.pop();
22     int x=(n-1)%(k-1);//共需要归并n-1个数,每次要归并k-1个数
23     int add=0;
24     if(x){//为了不影响单调性
25         x++;//每一次都是减去X个,又加一个。
26         add+=sum[x];
27         que.push(add);//先去掉x个,后面正常
28     }
29     gep(i,x+1,n) que.push(a[i]);
30     int y=(n-1)/(k-1);//分步骤
31     gep(i,0,y-1){
32         int tmp=k;
33         int tt=0;
34         while(tmp--){//每次k个
35             int v=que.top();
36             que.pop();
37             tt+=v;
38         }
39         que.push(tt);//再压入
40         add+=tt;
41     }
42     return add<=m;//不超过m才行
43 }
44 int  main()
45 {
46     scanf("%d",&t);
47     while(t--){
48         scanf("%d%d",&n,&m);
49         mem(a,0);
50         mem(sum,0);
51         gep(i,1,n) {
52             scanf("%d",&a[i]);
53         }
54         sort(a+1,a+1+n);//要先排序
55         gep(i,1,n){
56             sum[i]=sum[i-1]+a[i];
57         }
58         int l=2,r=n;//至少2个
59         while(l<=r){//r可能取到
60             int mid=(r+l)>>1;
61             if(check(mid)) r=mid-1;//r=mid是错的,会死循环
62             else l=mid+1;
63         }
64         printf("%d\n",r+1);
65     }
66     return 0;
67 }

 

转载于:https://www.cnblogs.com/tingtin/p/9477560.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值