Ice Cream Tower Gym - 101194D (貪心 + 二分 )
阿新 • • 發佈:2018-12-16
題目連結 : https://cn.vjudge.net/problem/Gym-101194D
題目大意 : 給你n個冰激凌球,讓你用這些冰激凌球去壘冰激凌,要求是下面的這一個必須是他上面一個的兩倍大,一個冰激凌需要m個冰激凌,問你最多能造幾個冰激凌.
具體思路: 貪心 + 二分 ,首先對輸入的n個冰激凌球進行排序,從小到大開始,然後對答案進行二分,從當前的開始,找第一個滿足的,然後找完一個再繼續找下一個,如果當前要檢測的答案是k,那麼就需要找k層滿足情況的.
AC程式碼:
#include<bits/stdc++.h> using namespace std; # define ll long long # define inf 0x3f3f3f3f const int maxn = 500000+10; ll a[maxn],b[maxn]; ll n,m; ll Max(ll t1,ll t2) { if(t1<t2)return t2; return t1; } bool judge(ll t) { ll ans=0; for(int i=1; i<=t; i++) { b[i]=a[i]; } int x=1; if(x==m)return true; int f=t; while(1) { for(int i=1; i<=t; i++) { if(f>=n)return false; f++; while(1) { if(a[f]>=b[i]*2) { b[i]=a[f]; break; } if(f+1>n)return false; f++; } } x++; if(x==m)return true; } } int main() { ll T; scanf("%lld",&T); int Case=0; while(T--) { scanf("%lld %lld",&n,&m); for(ll i=1; i<=n; i++) { scanf("%lld",&a[i]); } sort(a+1,a+n+1); ll l=0,r=n/m; ll ans=0; while(l <= r ) { int mid = ( l + r ) / 2; if(judge(mid)) { ans=Max( ans, mid ); l = mid + 1 ; } else r = mid - 1 ; } printf("Case #%d: ",++Case); printf("%lld\n",ans); } return 0; }