算法:二分答案
算法分析:我们发现答案处于区间$[0, n]$中。对于答案$x$,构造函数$f(x)$。$f(x)$表示完成$x$题所需要的最少时间。不难发现,当$x$变大时,$f(x)$的值增大。即:$f(x) < f(x + 1)$,该函数具有单调性,可以二分。$f(x)$的计算:该问题可以抽象为给定一个长度为$x$的窗口,求出所有窗口中和的最小值。我们可以考虑前缀和,快速求出窗口的和并实时更新ans。
复杂度:$O(nlogn)$
总结:二分答案将求解答案转化为判定答案。对于判定一个答案,我们通常将其划分为候选答案和非候选答案。通过二分的逐次迭代找到最优解。
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 100010;
int n, t;
int a[N], s[N];
int f(int mid) {
int ans = INT_MAX;
for (int i = 0, j = i + mid; j <= n; i ++, j ++) {
int tmp = s[j] - s[i];
ans = min(ans, tmp);
}
return ans;
}
int main() {
cin >> n >> t;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
}
for (int i = 1; i <= n; i ++) {
s[i] = s[i - 1] + a[i];
}
int l = 0, r = n;
while (l < r) {
int mid = (l + r + 1) >> 1;
int tmp = f(mid);
if (tmp <= t) l = mid;
else r = mid - 1;
}
cout << l << endl;
return 0;
}