这题一看很容易想到二分,但我一开始想偏了,我是想枚举天数,然后二分去验证天数是否满足,但是这样二分验证天数是否满足这一步卡住了,写不出来。
然后我改成二分天数,验证天数是否满足这一步改成暴力计算,这样的话总的时间复杂度还是O(n*logn)
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a[200005];
ll n,m,ss=0;
ll query(ll k)
{
ll val=0;
for(int i=n;i>n-k;i--)
{val+=a[i];}
if(val>=m)
{return 1;}
ll r=-1;
ll j=n-k,t,flag=0;
while(j>=1)
{
t=k;
while(t--)
{
if(a[j]+r>0)
{val+=(a[j]+r);}
else
{flag=1;break;}
j--;
}
if(flag)
{break;}
r--;
}
if(val>=m)
{return 1;}
else
{return -1;}
}
int main()
{
scanf("%lld %lld",&n,&m);
for(int i=1;i<=n;i++)
{scanf("%lld",&a[i]);
ss+=a[i];}
if(ss<m)
{printf("-1\n");
return 0;}
sort(a+1,a+1+n);
ll x=1,y=n,op,ans;
while(x<=y)
{
ll mid=(x+y)>>1;
op=query(mid);
if(op==1)
{y=mid;}
if(op==-1)
{x=mid;}
if(x==y)
{ans=x;break;}
if(x==y-1)
{
if(query(x)==1)
{ans=x;break;}
ans=y;
break;
}
}
printf("%lld\n",ans);
return 0;
}