题目链接:http://codeforces.com/contest/1118/problem/D2
题意:现在你有n杯咖啡m个任务,每一杯可以帮你完成ai个任务,如果你一天喝多杯咖啡,那么第二杯只能帮助你完成ai-1个任务,依类推次如果你喝k杯,第k杯只能完成(ak-k+1)个任务。现在你要选择最少的天数完成所有的任务,如果不可能完成输出-1。
解题心得:
- 一开始就想到了二分,二分天数,然后去检验这么多天能否完成。
- 结果自己脑子真的是铁得不行,检验方法想了半天没想出来。其实直接将ai降序排序,然后先依次每天安排一个任务,然后再每天依次安排第二个任务,这样直到ak-k+1<=0结束就行了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 100;
typedef long long ll;
typedef pair<int, int> P;
ll n, m, num[maxn], tot;
bool cmp(int a, int b) {
return a > b;
}
void init() {
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%lld", &num[i]);
tot += num[i];
}
sort(num + 1, num + 1 + n, cmp);
}
bool checke(ll days) {
ll sp = 0, sum = 0;//sp代表的是第k轮安排任务损耗的值
for (int i = 1; i <= n; i++) {
if(sp > num[i]) break;
sum += num[i] - sp;
if(i % days == 0) sp++;//每天已经安排了任务开始安排一天中的更多个任务
}
return sum >= m;
}
ll binary_search() {
if (m > tot) return -1;
ll l = 0, r = n + 1;
while (r - l > 1) {
ll mid = (l + r) >> 1;
if (checke(mid))
r = mid;
else
l = mid;
}
return r;
}
int main() {
//freopen("1.in", "r", stdin);
init();
ll ans = binary_search();
printf("%lld", ans);
return 0;
}