题目链接:https://codeforces.com/contest/1118/problem/D2
题意是有n杯咖啡,m页论文,然后是每杯咖啡所含的咖啡因,然后每天可以喝任意杯咖啡,如果这一天喝了很多杯咖啡的话,第一杯咖啡的咖啡因就是ai,第二杯的咖啡因就是ai-1,第三杯就是ai-2,一个咖啡因可以完成1页的论文,问最少需要几天可以写完这篇论文。
对于D1和D2的不同点就在于数据范围不同,那么D2可以过的话,D1就一定能过,对于D1来说,n只有100,所以写论文的天数最多也就100天,所以我们可以从1到n暴力枚举天数,如果可行i就是最少天数,那么判断是否可行的方法就是我们先让i天每天喝一杯咖啡,而且是咖啡因含量从大到小排序,如果不够m页的话,再依次让i天每天喝两杯咖啡,以此类推看能否完成m页的论文。那么D2就不能1-n枚举了,但是也不难想到二分天数,然后也是根据这个条件去判断就好了。下面只贴D2的呆码。
AC代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m;
ll pre[200005];
bool cmp(ll a,ll b){
return a > b;
}
bool Check(ll x){
ll ans = 0;
for(int i=0;i<n;i++){
ans += max(0LL, (ll)pre[i] - (i / x));
}
return ans >= m;
}
int main()
{
scanf("%lld%lld",&n,&m);
ll sum = 0;
for(int i=0;i<n;i++){
scanf("%lld",&pre[i]);
sum += pre[i];
}
sort(pre, pre + n, cmp);
if(sum < m){
puts("-1");
return 0;
}
ll l = 1, r = n, mid, ans = -1;
while(l <= r){
mid = (l + r) >> 1;
if(Check(mid)){
r = mid - 1;
ans = mid;
}
else{
l = mid + 1;
}
}
cout<<ans<<endl;
return 0;
}