The 2016 ACM-ICPC Asia China-Final Contest Gym - 101194D Ice Cream Tower

题意:熊猫先生想用一些冰淇淋球来做k层的冰淇淋,规定对于一个冰淇淋中的每一个冰淇淋球(最顶层除外),都大于等于上一层的冰淇淋球的两倍大小;现有n个冰淇淋球,问最多能做几个冰淇淋

思路:刚开始想的贪心,最后发现是不行的。比如对于 1 2 3 4 这种情况,1 后面是2还是3就没法用程序来进行抉择了。可以用二分的方法,枚举所有可能的冰淇淋个数x,然后再进行判断当前的冰淇淋球能否做成x个冰淇淋

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 3e5 + 100;
 5 ll ans[maxn], tmp[maxn];
 6 int n, k;
 7 
 8 bool judge(int len) {
 9     for(int i = 1; i <= len; i++)
10         tmp[i] = ans[i];
11     int cur = len+1;
12     for(int i = 1; i < k; i++) {
13         for(int j = 1; j <= len; j++) {
14             bool flag = false;
15             for(int z = cur; z <= n; z++) {
16                 if(ans[z] >= tmp[j]*2) {
17                     tmp[j] = ans[z];
18                     cur = z+1;
19                     flag = true;
20                     break;
21                 }
22             }
23             if(!flag) return false;
24         }
25     }
26     return true;
27 }
28 
29 int main() {
30 //    freopen("in.txt", "r", stdin);
31     int t, kase = 1;
32     scanf("%d", &t);
33     while(t--) {
34         scanf("%d%d", &n, &k);
35         for(int i = 1; i <= n; i++)
36             scanf("%lld", &ans[i]);
37         if(k == 1) {
38             printf("Case #%d: %d\n", kase++, n);
39             continue;
40         }
41         sort(ans+1, ans+1+n);
42         int l = 1, r = n/k+n%k+1;
43         while(l < r) {
44             int mid = (l + r) / 2;
45             if(judge(mid))
46                 l = mid + 1;
47             else r = mid;
48         }
49         printf("Case #%d: %d\n", kase++, l-1);
50     }
51 }

猜你喜欢

转载自www.cnblogs.com/tcctw/p/9748102.html