简单说一下题目,有n杯咖啡,第i杯能量为ai,一天之内可以喝任意杯,喝x杯可以写 a1+max(a2-1,0)+max(a3-2,0)+...+max(ax-x+1,0)篇文章,求最少要多长时间写完文章.(喝掉咖啡写的文章数>=要写的文章数m)
这又是一道二分查找的问题,通过问题的描述我们知道,做多能写∑ai篇文章(一天一杯),于是如果总篇数m大于∑ai那么这是无解的.
接下来讨论有解的情况,我们可以推解,如果给定时间day,最多能写的文章数可以求出来(这类似于并查集的压缩,合并一个咖啡到一天,就会多减去一个数,该数为改天原咖啡杯数的大小,只要每次选择咖啡数最小的一天,就可以把减去的数降到最低),用作二分的判端.解的范围想必大家都知道了[0,n];
下面是代码
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; int n,m; ll a[(int)2e5+5]; bool check(int day) { ll s=0; for(int i=0;i<n;i++)s+=max(a[n-1-i]-(i/day),(ll)0); return s>=m; } int main() { // freopen("ini","r",stdin); cin>>n>>m; ll sum=0; for(int i=0;i<n;i++){scanf("%lld",&a[i]);sum+=a[i];} sort(a,a+n); if(sum-m<=0){ if((sum-m)==0)cout<<n; else cout<<-1<<endl; return 0; } int l=0,r=n; while(l+1<r){ // cout<<r<<endl; int mid=(l+r)>>1; if(check(mid))r=mid; else l=mid;//l not ans } cout<<r<<endl; return 0; }