传送门
二分,枚举答案
如果验证是否能给mid个充电器都充电
那当然是给更安全的充电器充电
然后对于每个充电器是否能充电,总是先尽可能插插线板,然后充电
Code:
#include <bits/stdc++.h>
#define maxn 400010
#define LL long long
using namespace std;
int n, m, a[maxn], b[maxn];
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
bool cmp(int x, int y){ return x > y; }
bool check(int mid){
int A = 1, B = 0, k = mid, i = 1, L = 0;
while (k <= m){
while (L < b[k] && A && i <= n){
--A, B += a[i++];
if (!A) A = B, B = 0, ++L;
}
if (!A || L > b[k]) return 0;
if (L < b[k]) A += B, B = 0;
--A, ++k;
if (!A) A = B, B = 0, ++L;
}
return k > m;
}
int main(){
n = read(), m = read();
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1; i <= m; ++i) b[i] = read();
sort(a + 1, a + 1 + n, cmp);
sort(b + 1, b + 1 + m);
int l = 1, r = m, ans;
while (l <= r){
int mid = (l + r) >> 1;
if (check(mid)) ans = max(ans, m - mid + 1), r = mid - 1; else l = mid + 1;
}
printf("%d\n", ans);
return 0;
}