题解 | #环路运输# 单调队列

环路运输

https://ac.nowcoder.com/acm/problem/51187

Solution

首先观察题目中的定义可以得知,在不区分前后关系的时候判断很复杂。

我们对于这种环形的办法一般都是断环成链,复制一份。

那么这样处理之后,就可以永远保证按照这种的方式求解不会漏掉情况,并且每次我们每次往前选择的

。接下来就是维护转换方程了。

我们要求解的答案是

定长区间的最值问题,使用单调队列求解。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, sta, en) for(int i=sta; i<=en; ++i)
#define repp(i, sta, en) for(int i=sta; i>=en; --i)
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(ll x, int op = 10) { if (!x) { putchar('0'); if (op)    putchar(op); return; }    char F[40]; ll tmp = x > 0 ? x : -x;    if (x < 0)putchar('-');    int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';        tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]);    if (op)    putchar(op); }

const int N = 1e6 + 7;
int n, m, a[N << 1];
deque<int> q;

int main() {
    n = read();
    rep(i, 1, n)    a[i] = read(), a[i + n] = a[i];
    m = n >> 1;
    n = n << 1;
    int ans = 0;
    rep(i, 1, n) {
        while (q.size() and i - q.front() > m)    q.pop_front();
        if (q.size())    ans = max(ans, a[i] + a[q.front()] + i - q.front());
        while (q.size() and a[i] - i > a[q.back()] - q.back())    q.pop_back();
        q.push_back(i);
    }
    print(ans);
    return 0;
}
每日一题 文章被收录于专栏

每日一题

全部评论

相关推荐

点赞 评论 收藏
分享
面试摇了我吧:啊哈哈面试提前五个小时发,点击不能参加就是放弃
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务