51nod 1437 迈克步

题目链接

先利用单调栈or其他方法找到一个元素g[i]作为最小值的区间,设为[L, R]。

那么长度为R-L+1的组的最大值ans=max(ans,g[i])。但是有一个问题:

比如6这个元素是长度为3的组的最大值,长度为2的最大值之前更新到为4,那么实际上长度为2的最大值是多少呢?

自然是6,因为肯定6存在于长度为2的组。

于是:求得所有元素作为最小值的组的长度后,更新每个长度的最大值。然后从长度最大的组往长度小的刷新,因为:能在长度大的做最小元素,也能在长度小的组做最小元素。

所以得到ans[]后需要一个操作刷新:

for (int i = N - 1; i >= 1; --i)
    ans[i] = max(ans[i], ans[i + 1]);

最后的代码:

#include <stdio.h>
#include <algorithm>
using namespace std;

const int maxN=2e5+5;
int N, M, K, T;
int g[maxN], L[maxN], R[maxN];
int ans[maxN];

int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif
    scanf("%d", &N);
    for (int i = 1; i <= N; ++i)
        scanf("%d", g + i);
    for (int i = 1; i <= N; ++i)
        L[i] = i - 1, R[i] = i + 1;
    for (int i = 1; i <= N; ++i)
        while (L[i] && g[L[i]] >= g[i])
            L[i] = L[L[i]];
    for (int i = N; i >= 1; --i)
        while (R[i] <= N && g[R[i]] >= g[i])
            R[i] = R[R[i]];

    for (int i = 1; i <= N; ++i) {
        int siz = R[i] - L[i] - 1;
        ans[siz] = max(ans[siz], g[i]);
    }
    for (int i = N - 1; i >= 1; --i)
        ans[i] = max(ans[i], ans[i + 1]);
    for (int i = 1; i <= N; ++i)
        printf("%d ", ans[i]);
    puts("");
    return 0;
}
原文地址:https://www.cnblogs.com/Rosebud/p/9523862.html