二分+DP+单调队列优化绿色通道 LibreOJ - 10181

Posted Vincent_0000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分+DP+单调队列优化绿色通道 LibreOJ - 10181相关的知识,希望对你有一定的参考价值。

题目来源

点我进入提交题目

反思

这个题目刚开始做的时候就已经把自己扼杀在摇篮里面了,因为自己在刷单调队列优化DP嘛,看到这个题目有很明显的二分性质的时候就想:这个题目在考DP,不会考二分的,二分肯定有坑,然后就直接放弃了。然后往其他方向也没想出对应的方案出来。

所以说,看到题目有一些基础算法的影子的时候,不要直接放弃,多尝试一下,说不定试着试着就对了呢。

题解

  • 根据题目初步分析类型

n 道题目 每道题 a i a_i ai分钟,总共时常不超过t,求最小的最长空题段长。

看到最小值的最大值这类字眼要很敏感,做类似这样的题目尝试用二分的思路去解答。

  • 进一步思考

既然考虑使用二分,那么我们就要看看这个题目是否符合二分的性质,最优解的右边是一定能够符合题解的(后面的空题段长比最优解段长长,段长越长,我们花费的时间也就越短,也就一定能够符合题意。),而他的左边是不符合题意的(段长越短,时间也就会越长,因为最优解一定是在完成作业的边缘,时间只要长一点点,那么就会不符合题意)。
完全符合二分的特征,可以使用二分去做这一题。

二分之后怎么去判断呢?
二分枚举的的段长(二分实现最小),那么题目就转化为了,已知段长 x x x,在段长不超过x的情况下(实现长度最大),求所花费最小时间T(最小时间保证长度是最大的), 当 T ≤ t T \\leq t Tt 时,符合题意。

这个子题目其实是这个题目:点我查看
思路是一模一样的,就不多讲了。

代码中有一个细节需要注意:
我们给定的空格是x个,但是我们滑动窗口的大小要是x + 1个,因为遇到的两个数之间可以有x个空格,那么再加上前一个可以用的空格,那么就是x + 1个空格。

AC代码

#include<bits/stdc++.h>
using namespace std;

#define _for(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(a) cout << #a << " = " << a << endl
#define mod(x) (x) % MOD
#define ENDL "\\n"
#define x first
#define y second
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 5e4 + 7, MOD = 1e9, INF = 0x3f3f3f3f;
int q[N], f[N], a[N], n, t;

bool check(int x) {
    int hh = 0, tt = 0, ans = INF;
    _for(i,  1, n) {
        if (hh <= tt && i - q[hh] - 1 > x) ++hh;
        f[i] = f[q[hh]] + a[i];
        while (hh <= tt && f[i] <= f[q[tt]]) --tt;
        q[++tt] = i;

        if (i >= n - x) ans = min(ans, f[i]);
    }
    return ans <= t;
}

int main()
{
#ifdef LOCAL
    freopen("data.in", "r", stdin);
#endif
    ios::sync_with_stdio(false);
    cout.tie(0), cin.tie(0);

    cin >> n >> t;
    _for(i, 1, n) cin >> a[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 <<endl;
    return 0;
}

以上是关于二分+DP+单调队列优化绿色通道 LibreOJ - 10181的主要内容,如果未能解决你的问题,请参考以下文章

单调队列优化DP 旅行问题 LibreOJ - 10178

单调队列优化dp题目

codevs3342绿色通道(单调队列优化dp)

绿色通道 单调队列优化DP

[bzoj2806][Ctsc2012]Cheat(后缀自动机(SAM)+二分答案+单调队列优化dp)

BZOJ2806[Ctsc2012]Cheat 广义后缀自动机+二分+单调队列优化DP