题目链接
思路:想要二分的找到最小需要看的天数的话,其实就应该要求出在一定天数间能获得的最大知识点。贪心策略就是优先看知识点数高的书。所以我们可以先将原序列按知识点从大到小排列,再按照看书天数将书分为不同集合。如:有序列为5,4,3,2,1的书要在2天看完,那么5,4就是每天看的第一本书,3,2就是每天看的第二本书,1就是第一天看的第三本书。
ac代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <map>
using namespace std;
#define int long long
int cnt[1000005]; int n, m;
bool cmp(int a, int b) {
return a > b;
}
bool check(int t) {
int sum = 0;
for (int i = 0; i < n; i++) {
if (cnt[i] - i / t <= 0) break;
sum += (cnt[i] - i / t);
}
if (sum >= m) return true;
else return false;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> cnt[i];
sort(cnt, cnt + n,cmp);
int l = 1, r = n; int ans = -1;
while (l <= r) {
int mid = (l + r) / 2;
if (check(mid)) {
ans = mid; r = mid - 1;
}
else l = mid+1;
}
cout << ans << endl;
return 0;
}