Ice Cream Tower Gym - 101194D

Input file: Standard Input

Output file: Standard Ouptut

Time limit: 6 seconds

接着整理奥,2016 ACM-ICPC Asia China-Final的D题。

题目大意:输入n和k,给出n个ice cream balls的大小,k个balls可以组成一个Tower,且里面每下面一层ball的大小>=2*上面一层ball的大小,

求最多能组成几个Towers。

一开始想的只有贪心:从最大的ball开始找,找到一个就加上,尽量剩下小的,可以更好组成Towers。

结果还需要二分,而且一开始的想法也不太对(至于为什么我也不太清楚..菜鸡哭了),是先贪小的,在1到n里随机取1个数,作为求解的结果num,将所有小的作为num个Tower的顶层,然后

往下加层数,直到k层。然后不断二分查找到最大的num值就可以了。

代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 int T,n,k,cas=1;
 6 long long a[300005],ceng[300005];//二分+贪心
 7 bool isvalid(int b)
 8 {
 9     int i=0;
10     for(i=0; i<b; i++)
11         ceng[i]=a[i];//当前层的每个的大小
12     for(int j=1; j<k; j++)//对于除了第一层的剩余k-1层
13         for(int p=0; p<b; p++)
14         {
15             while(a[i]<2*ceng[p])
16             {
17                 i++;
18                 if(i>=n)
19                     return false;
20             }
21             ceng[p]=a[i];
22             i++;
23         }
24     return true;
25 }
26 int main()
27 {
28     cin>>T;
29     while(T--)
30     {
31         memset(a,0,sizeof(a));
32         memset(ceng,0,sizeof(ceng));
33         cin>>n>>k;
34         for(int i=0; i<n; i++)
35             cin>>a[i];
36         if(k==1)
37         {
38             cout<<"Case #"<<cas++<<": "<<n<<endl;
39             continue;
40         }
41         sort(a,a+n);
42         int star=0,endd=n+1;
43         while(endd-star>1)//二分查找
44         {
45             int mid=(star+endd)/2;
46             if(isvalid(mid))
47                 star=mid;
48             else
49                 endd=mid;
50         }
51         cout<<"Case #"<<cas++<<": "<<star<<endl;
52     }
53     return 0;
54 }

猜你喜欢

转载自www.cnblogs.com/shangqing/p/11255582.html