1. 程式人生 > 實用技巧 >【資料結構】CF1407D - Discrete Centrifugal Jumps

【資料結構】CF1407D - Discrete Centrifugal Jumps

一個很複雜的單調棧,注意幾個樣例:

4 2 3 2 3

答案是2

因為從4可以到第1個3,但是不能到第2個3。但是第1個3是應該要出棧的,因為有第2個3卡住之後,第1個3沒有更新後續的機會。也就是說,他要出棧,但是卻不能更新。

const int MAXN = 300000 + 5;
 
int n;
int h[MAXN];
int dp[MAXN];
 
stack<int> s1, s2;
 
void solve() {
    n = readInt();
    for(int i = 1; i <= n; ++i) {
        h[i] = readInt();
        dp[i] = INF;
    }
    dp[1] = 0;
    s1.push(1);
    s2.push(1);
    for(int i = 2; i <= n; ++i) {
        dp[i] = min(dp[i], dp[i - 1] + 1);
        while(!s1.empty() && h[s1.top()] >= h[i]) {
            dp[i] = min(dp[i], dp[s1.top()] + 1);
            int htop = h[s1.top()];
            s1.pop();
            if(!s1.empty() && htop != h[i])
                dp[i] = min(dp[i], dp[s1.top()] + 1);
        }
        s1.push(i);
        while(!s2.empty() && h[s2.top()] <= h[i]) {
            dp[i] = min(dp[i], dp[s2.top()] + 1);
            int htop = h[s2.top()];
            s2.pop();
            if(!s2.empty() && htop != h[i])
                dp[i] = min(dp[i], dp[s2.top()] + 1);
        }
        s2.push(i);
    }
    while(!s1.empty())
        s1.pop();
    while(!s2.empty())
        s2.pop();
    printf("%d\n", dp[n]);
    return;
}