// 1090. 绿色通道.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <deque>
using namespace std;
/*
* https://www.acwing.com/problem/content/1092/
高二数学《绿色通道》总共有 n道题目要抄,编号 1,2,…,n,抄第 i题要花 ai分钟。
小 Y 决定只用不超过 t 分钟抄这个,因此必然有空着的题。
每道题要么不写,要么抄完,不能写一半。
下标连续的一些空题称为一个空题段,它的长度就是所包含的题目数。
这样应付自然会引起马老师的愤怒,最长的空题段越长,马老师越生气。
现在,小 Y 想知道他在这 t 分钟内写哪些题,才能够尽量减轻马老师的怒火。
由于小 Y 很聪明,你只要告诉他最长的空题段至少有多长就可以了,不需输出方案。
输入格式
第一行为两个整数 n,t。
第二行为 n个整数,依次为 a1,a2,…,an。
输出格式
输出一个整数,表示最长的空题段至少有多长。
数据范围
0<n≤5×104
,
0<ai≤3000
,
0<t≤108
输入样例:
17 11
6 4 5 2 5 3 4 5 2 3 4 5 2 3 6 3 5
输出样例:
3
*/
const int N = 50010;
int arr[N];
int dp[N];
int n, t;
bool check(int x) {
memset(dp, 0x3f, sizeof dp);
dp[0] = 0;
deque<int> q;
q.push_back(0);
for (int i = 1; i <= n; i++) {
while (!q.empty() && i-q.front() > x+1) q.pop_front();
dp[i] = arr[i] + dp[q.front()];
while (!q.empty() && dp[q.back()] >= dp[i]) q.pop_back();
q.push_back(i);
}
int ans = 99999999;
for (int i = n; i >= max(0,n - x); i--) {
ans = min(ans,dp[i]);
}
return ans <= t;
}
int main()
{
//cin >> n >> t;
scanf("%d%d",&n,&t);
for (int i = 1; i <= n; i++) {
//cin >> arr[i];
scanf("%d",&arr[i]);
}
int l = 0; int r = n;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid) == true) {
r = mid;
}
else {
l = mid + 1;
}
}
//cout << l << endl;
printf("%d\n",l);
return 0;
}
标签:1090,int,back,mid,绿色通道,空题,ans,dp
From: https://www.cnblogs.com/itdef/p/18253893