1090. 绿色通道

高二数学《绿色通道》总共有 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
思路:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q6ymmw8c-1648819148116)(1090.%20%E7%BB%BF%E8%89%B2%E9%80%9A%E9%81%93.assets/7416_24ab61b809-e1587cad3cfab5744b6976e95695dfa.png)]

/*
二分 + 滑动窗口

1、给定某个长度,若该长度满足条件,就变长继续观察,不满足则变短继续观察,直到找到最小符合的长度值,因此使用二分
2、check函数中,给定最长的空题段的长度是mid,求出满足题意的花费时间最小值res,判断res <= t是否成立
3、由于最长的空题段的长度是k = mid,传进check()函数的变量是k,因此滑动窗口的长度是mid + 1,
以i结尾的f[i],滑动窗口的区间是[i - (k + 1),i - 1],单调队列维护的是该区间的最小值,由于滑动窗口不包含i,因此f[i]需要在while上方进行更新

*/
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10, INF = 0x3f3f3f3f;

int n, m;
int w[N];
int f[N], q[N];
int check(int k)// 能出现的最长空白
{
    memset(f, 0, sizeof(f));
    memset(q, 0, sizeof(q));

    f[0] = 0; // 一开始的m个f[i]都由f[0]转移而来 区间最小值设为q[0] = 0,f[0] = 0;
    int hh = 0, tt = 0;
    for (int i = 1; i <= n; i++)
    {
        if (hh <= tt && q[hh] < i - k - 1)
            hh++;
        f[i] = f[q[hh]] + w[i];
        while (hh <= tt && f[i] <= f[q[tt]])
            tt--;
        q[++tt] = i;
    }

    int res = INF;
    for (int i = n - k; i <= n; i++)
        res = min(res, f[i]);

    return res <= m;
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> w[i];

    int l = 0, r = n;
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid))
            r = mid;
        else
            l = mid + 1;
    }

    cout << l;

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追寻远方的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值