101194 D Ice Cream Tower 二分 + 貪心判斷
阿新 • • 發佈:2018-12-14
1.題意:給你n個冰激凌球的體積,告訴你k個球能合成一個冰激凌,合成條件是放在第一個球下面的球體積要大於等於他的兩倍。問你最多能合成多少個。
2.分析:
最少能合成0個,最多能合成n/k個。存在單調性上下界,於是我們二分合成數量。
怎麼判斷mid個能否合成呢?我們知道最上面的球體積越小,可選擇的情況越多,合成得最多!所以既然要合成mid個,我們就選前mid個作為mid個冰激凌的頂部,以此類推選下一個底,看看能否合成mid個即可。
3.程式碼:
#include <iostream> #include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 300000 + 100; LL num[maxn],check[maxn]; int n,k; bool judge(int u){ int i; for(i = 0;i<u;i++)check[i] = num[i];//前mid個作為頂球 for(int p = 1;p<k;p++){//每一個要選k個合成 for(int j = 0;j<u;j++){//進行u次 if(i>=n)return false; int pos = lower_bound(num+i,num+n,check[j]*2) - num; if(pos>=n){ return false; } check[j] = num[pos]; i = pos+1; } } return true; } int main() { int T; scanf("%d",&T); int t = 0; while(T--){ t++; scanf("%d%d",&n,&k); for(int i = 0;i<n;i++){ scanf("%lld",&num[i]); } if(k==1){ printf("Case #%d: %d\n",t,n); continue; } sort(num,num+n); int l = 0,r = n/k; int ans = 0; while(l<=r){//二分 int mid = (l + r)/2; if(judge(mid)){//判斷mid個能否合成 ans = mid; l = mid+1; } else r = mid-1; } printf("Case #%d: %d\n",t,ans); } return 0; }