N 頭牛排成一排(N≤50000),每頭牛有高度 h[i]。牛 i 向右看,能看到多少頭牛?只能看到比自己矮的,遇到 ≥ 自身高度的牛視線被擋住。求所有牛看到的牛數之和。
維護一個單調遞減棧(棧底到棧頂高度遞減)。從右向左遍歷:
i,高度 h[i]h[top] < h[i] 的牛(它們被 i 看見,且不再被更左的牛看見)i 能看到的牛數i 入棧h[j] < h[i] 且 在 i 右側,則 i 一定能看見 j(中間沒有更高的擋住)j 不會再被更左的牛看見,因為 i 已經擋住視線#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N; cin >> N;
vector<int> h(N);
for (int i=0;i> h[i];
vector<int> stk; stk.reserve(N);
ll ans = 0;
for (int i=N-1; i>=0; --i) {
int cnt = 0;
while (!stk.empty() && h[stk.back()] < h[i]) {
stk.pop_back();
cnt++;
}
ans += cnt;
stk.push_back(i);
}
cout << ans << "\n";
return 0;
}
h[top] < h[i] 彈出)h[top] ≤ h[i] 彈出)| 問題類型 | 棧單調性 | 遍歷方向 | 典型題 |
|---|---|---|---|
| 右側第一個更大/更小 | 遞減/遞增 | 右→左 | 每日氣溫、直方圖最大矩形 |
| 左側第一個更大/更小 | 遞減/遞增 | 左→右 | 接雨水、最大子矩陣 |
| 可見對數/可見數量 | 遞減 | 右→左 | Bad Hair Day、看守安排 |