The 2016 ACM-ICPC Asia China-Final D. Ice Cream Tower 二分 + 贪心

 

题目大意:ios

对于给出的n个冰激凌球的大小,知足下面的球的大小是上一个的至少2倍,对于给出的k(由k的冰激凌球才能算做一个冰激凌塔),问n个冰激凌球能够最多堆出多少个高度为k的冰激凌塔数组

题目分析:函数

对于n个冰激凌球,显然咱们得知能够堆出的高度为k的塔的数量在0~[n / k]之间,这里能够经过二分遍历每一种可能,初始时二分边界l==0,r==[n / k],每次取中间值mid=(l+r)/ 2,判断mid高度为k的塔可否堆出,若是能够则尝试mid为更大,不然则尝试mid为更小时,不断二分尝试mid是否可行,而对于每一个mid,咱们要写一个判断函数,来判断mid座高度为k的冰激凌塔可否堆出,这里用到了贪心的思惟,咱们先对n个冰激凌球的大小进行从小到大的排序,而后对于mid座塔咱们只要建立一个一维数组,0~mid-1放置排完序的冰激凌球的前mid个(因为已经将冰激凌球排序,取出前mid个放入这个数组便可),而后循环k-1遍(由于高度初始已经为1,只要再判断k-1层的状况便可),从编号为mid开始依次选取冰激凌球(从小到大)与这个0~mid-1个位置进行比较,若是知足是它的至少两倍则更新0~mid-1位置的冰激凌球大小,不然继续日后找一个知足的冰激凌球去替换它,完成了一层以后则继续从0~mid-1开始(共k层),假如中途出现冰激凌球已经遍历到最后,可是仍是k层冰激凌塔没有完成堆叠,则返回失败,不然在结束全部k层的每一个判断后返回成功spa

关于贪心的部分,因为数组是从小到大排序的,若是遇到一个位置不知足是它的至少两倍则将下标日后移动,前面的就被舍弃了(由于对后面的位置来讲,它必定是比前面位置大的,指向该下标的冰激凌球大小若是不知足前者至少两倍,则不可能知足后者的至少两倍关系,而从小到大排序选择也是知足了最优的选择方案,先用小的试探,后用大的试探,小的必定在前面)code

代码:blog

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 using namespace std;
 5 
 6 const int M = 300005;
 7 long long ice[M];
 8 long long update[M];
 9 int n, k;
10 
11 bool judge(int x){        //x表明判断作x个塔是否可行 
12     for(int i = 0; i < x; i++){
13         update[i] = ice[i];
14     }
15     int cnt = x;
16     for(int i = 1; i < k; i++){
17         for(int j = 0; j < x; j++){
18             while(update[j]*2 > ice[cnt] && cnt < n) cnt++;
19             if(cnt == n) return false;
20             update[j] = ice[cnt];
21             cnt++;    
22         }
23     }
24     return true;
25 }
26 
27 int main(){
28     int t;
29     scanf("%d", &t);
30     int cnt = 1;
31     while(t--){
32         scanf("%d%d", &n, &k);
33         for(int i = 0; i < n; i++) scanf("%lld", &ice[i]);
34         sort(ice, ice + n);
35         int l = 0;
36         int r = n/k;
37         int ans = 0;
38         while(l <= r){
39             int m = (l+r)/2;
40             if(judge(m)){
41                 l = m+1;
42                 ans = m;
43             }else{
44                 r = m-1;
45             }
46         }
47         printf("Case #%d: %d\n", cnt++, ans);
48     } 
49     return 0;
50 }
相关文章
相关标签/搜索