题意:熊猫先生想用一些冰淇淋球来做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 }
原文地址:https://www.cnblogs.com/tcctw/p/9748102.html
时间: 2024-11-06 07:36:02