1090. 绿色通道
题目链接
1090. 绿色通道
高二数学《绿色通道》总共有 \(n\) 道题目要抄,编号 \(1,2,…,n\),抄第 \(i\) 题要花 \(a\_i\) 分钟。
小 Y 决定只用不超过 \(t\) 分钟抄这个,因此必然有空着的题。
每道题要么不写,要么抄完,不能写一半。
下标连续的一些空题称为一个空题段,它的长度就是所包含的题目数。
这样应付自然会引起马老师的愤怒,最长的空题段越长,马老师越生气。
现在,小 Y 想知道他在这 \(t\) 分钟内写哪些题,才能够尽量减轻马老师的怒火。
由于小 Y 很聪明,你只要告诉他最长的空题段至少有多长就可以了,不需输出方案。
输入格式
第一行为两个整数 \(n,t\)。
第二行为 \(n\) 个整数,依次为 \(a_1,a_2,…,a_n\)。
输出格式
输出一个整数,表示最长的空题段至少有多长。
数据范围
\(0 < n \le 5 \times 10^4\),
\(0 < a_i \le 3000\),
\(0 < t \le 10^8\)
输入样例:
17 11
6 4 5 2 5 3 4 5 2 3 4 5 2 3 6 3 5
输出样例:
3
解题思路
二分,单调队列优化dp
显然,本题具有单调性,即要使最小的空题段越小,所用的时间越多,故可以考虑二分答案 \(x-1\),问题就可以转化为在连续的长度为 \(x\) 的区间内必须选上一个数,因为如果没有在这样的一个区间内选数的话,空题段就能为 \(x\),比 \(x-1\) 更大,不合二分,故问题就转化为 1087. 修剪草坪 单调队列优化dp模板题
- 时间复杂度:\(O(nlogn)\)
代码
// Problem: 绿色通道
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/1092/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// %%%Skyqwq
#include <bits/stdc++.h>
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=5e4+5;
int n,t,a[N],q[N],hh,tt,f[N];
int ck(int x)
{
hh=0,tt=0;
for(int i=1;i<=n;i++)
{
f[i]=a[i];
while(hh<=tt&&i-1-q[hh]+1>x)hh++;
if(i>=x)f[i]+=f[q[hh]];
while(hh<=tt&&f[q[tt]]>=f[i])tt--;
q[++tt]=i;
}
int res=0x3f3f3f3f;
for(int i=max(0,n+1-x);i<=n;i++)res=min(res,f[i]);
return res<=t;
}
int main()
{
scanf("%d%d",&n,&t);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int l=1,r=n;
while(l<r)
{
int mid=l+r>>1;
if(ck(mid))r=mid;
else
l=mid+1;
}
printf("%d",l-1);
return 0;
}