Coffee and Coursework
题意:
泰泰学长必须写他的课程作业。他的课程作业包含m 页.
为了提高效率,泰泰学长从某多多上买了n 杯咖啡. 对于第 i 杯咖啡泰泰学长可以摄
取 ai 咖啡因. 泰泰学长打算喝一些咖啡来提高效率(每杯咖啡最多喝一次).他可以按照
任何顺序喝咖啡. 泰泰学长喝每杯咖啡会马上喝完并且一滴不剩 (也就是说他不能把
一杯咖啡分到两天喝).
当然,泰泰学长的课程作业不能一天写完(至少在现实生活中不能).
我们考虑泰泰学长工作的一些天。 考虑到泰泰学长喝k杯咖啡在这一天并且这写咖啡
含有的咖啡因为ai1 , ai2 … aik . 那么第一杯咖啡给他提供了写ai1页的能量, 第二杯
给他提供了写max(0 , ai2 - 1)页的能量, 第三杯给他写max(0 , ai3 - 2)页的能量, …,
第k杯给他写max(0 , aik - k + 1 )页的能量.
如果泰泰学长在某一天没有喝咖啡,那么他一页都不会写
泰泰学长必须尽快的完成他的课程作业(花费最少的天数去完成). 你的任务是求出泰泰
学长能够完成课程作业的最短时间。
思路:
简单二分,51nod上看见该题,题意描述的不清楚,补全题意,(不小心
看了题解),二分天数,然后求该天数下获得的最大权值和即可。
代码实现:
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<cstdio>
#include<algorithm>
#include<bits/stl_function.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=2e6+100;
const int mod=1e9+7;
int arr[N];
bool judge(int x,int n,int m){
int sum=0,p=1,cnt=0;
while(p<=n){
for(int i=1;i<=x;i++){//大权值分别往每天的前面放
sum+=arr[p]-cnt;
p++;
if(sum>=m)return 1;
if(p>n)break;
}
cnt++;
}
return 0;
}
int main() {
#ifdef MYHOME
freopen("input.txt","r",stdin);
#endif
int n,m,ans;
while(cin>>n>>m){
ans=-1;
for(int i=1;i<=n;i++)cin>>arr[i];
sort(arr+1,arr+1+n,greater<int>());
int l=1,r=n;
while(l<=r){
int mid=(l+r)/2;
if(judge(mid,n,m)){
ans=mid;
r=mid-1;
}else {
l=mid+1;
}
}
cout<<ans<<endl;
}
return 0;
}
THE END;