洛谷P2947 向右看齐Look Up 题解 单调栈/单调队列

题目链接:https://www.luogu.com.cn/problem/P2947

题目大意:
约翰的 \(N(1 \le N \le 10^5)\) 头奶牛站成一排,奶牛\(i\)的身高是\(H_i(l \le H_i \le 1,000,000)\).现在,每只奶牛都在向右看齐.对于奶牛\(i\),如果奶牛\(j\)满足 \(i \lt j\)\(H_i \lt H_j\) ,我们可以说奶牛\(i\)可以仰望奶牛\(j\) . 求出每只奶牛离她最近的仰望对象.

解题思路:

维护一个单调非递增的 单调队列 ,然后每次在第 \(i\) 投奶牛入队列之前,判断对位元素是否要出队,如果要出队,则对位元素的仰望对象就是 \(i\)

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, h[maxn], target[maxn];
deque<int> que;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> h[i];
    for (int i = 1; i <= n; i ++) {
        while (!que.empty() && h[que.back()] < h[i]) {
            target[que.back()] = i;
            que.pop_back();
        }
        que.push_back(i);
    }
    for (int i = 1; i <= n; i ++) cout << target[i] << endl;
    return 0;
}

因为进出元素都是队尾执行,所以我们可以用 单调栈 来实现同样的功能。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, h[maxn], target[maxn];
stack<int> stk;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> h[i];
    for (int i = 1; i <= n; i ++) {
        while (!stk.empty() && h[stk.top()] < h[i]) {
            target[stk.top()] = i;
            stk.pop();
        }
        stk.push(i);
    }
    for (int i = 1; i <= n; i ++) cout << target[i] << endl;
    return 0;
}
posted @ 2020-02-11 21:51  quanjun  阅读(366)  评论(0编辑  收藏  举报