1090. 绿色通道

// 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;
}

我的视频题解空间

posted on 2024-06-18 10:43  itdef  阅读(3)  评论(0编辑  收藏  举报

导航