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 #include<queue>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 100005;
 7 int n, m;
 8 int a[N];
 9 queue<ll>q1, q2;
10 int jud(int k){
11     while(!q1.empty()) q1.pop();
12     while(!q2.empty()) q2.pop();
13     //queue<ll>q1, q2;
14     int i;
15     int tt = (n-1)%(k-1);
16     ll t, s = 0;
17     if(tt){
18         for(i = 1; i <= k-1 - tt; ++i)
19             q1.push(0);//虚拟点
20     }
21     for(i = 1; i <= n; ++i)
22         q1.push(a[i]);
23     while(1){
24         t = 0;
25         int x1, x2;
26         for(i = 1; i <= k; ++i){
27             if(q1.empty() && q2.empty())
28                 break;
29             if(q1.empty()){
30                 t += q2.front(); q2.pop();
31                 continue;
32             }
33             if(q2.empty()){
34                 t += q1.front(); q1.pop();
35                 continue;
36             }
37             x1 = q1.front();
38             x2 = q2.front();
39             if(x1 < x2){
40                 t += x1; q1.pop();
41             }else{
42                 t += x2; q2.pop();
43             }
44         }
45         s += t;
46         if(q1.empty() && q2.empty())
47             break;
48         q2.push(t);//维护合并后的值
49     }
50     if(s <= m) return 1;
51     return 0;
52 }
53 void bi_search(){
54     int l = 2,r = n;
55     while(l < r){
56         int mid = l + (r - l)/2;
57         if(jud(mid))
58             r = mid;
59         else
60             l = mid + 1;
61     }
62     printf("%d\n", r);
63 }
64 int main(){
65     int t, i;
66     scanf("%d", &t);
67     while(t--){
68         scanf("%d%d", &n, &m);
69         for(i = 1; i <= n; ++i)
70             scanf("%d", &a[i]);
71         sort(a+1, a+1+n);
72         bi_search();
73     }
74     return 0;
75 }
View Code

 

posted @ 2016-09-18 21:49  GraceSkyer  阅读(1022)  评论(3编辑  收藏  举报

~~~~~~ACM大牛语录,激励一下~~~~~~

为了世界的和平,为了女生的安全,我拼命做题,做题,做题!

用最短的时间,刷最多的题!

给我一滴泪,我就看到了你全部的海洋!

seize the hour, seize the day.

人生难免有无奈,幸福走远了,或是感叹幸福来迟了.其实我一直相信,无论手中的幸福是多么微不足道的感觉,我会把握住那每一分,每一秒,当幸福依旧像那百鸟般飞逝,终究无法掌握时,我会感谢它,曾经降临过!

A自己的题,让别人郁闷去吧

WA肠中过,AC心中留 TLE耳边过,AC特别牛

天然的悲苦和伤逝,过去有过,以后还会有

^*^一步一步往上爬^*^

AC就像练级,比赛就像PK. 练级不如PK好玩

其实,世上本没有ACM,AC的人多了,也便有了!

AC无止尽~ Seek you forever~

找呀找呀找水题,找到一个AC一个呀!

AC是检验程序的唯一标准。

真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血……