試題J 冷嘲熱諷 25 單調棧

2021-10-04 23:35:15 字數 1089 閱讀 7100

鏈結 :

思路 :根據題意我們可以發現每乙個數的左邊相鄰的只要有比他小的數字,那麼這個數字就會被刪除,那麼我們可以維護乙個遞增的單調棧,然後使用乙個 stst

st的陣列來記錄當前值是第幾輪被刪除的,在維護遞增的單調棧的時候,我們可以發現如果棧頂的值是大於當前值的,那麼棧頂的元素將會被彈出,每維護乙個棧那麼進棧的第乙個元素就是這個相鄰區間的第乙個值,它後面乙個數如果有小於它的數字,那麼這個數字將會被刪除,然後將這個數入棧,如果後面沒有比他小的,也就是棧頂的值是大於當前值的那麼就一邊更新輪數,一邊刪除棧中的數,直到有小於他的數字,如果沒有那麼它將是進棧的第乙個元素,也就是不會被刪除。

#include

using namespace std;

typedef

long

long ll;

const

int maxn =

1e6+10;

int a[maxn]

, stk[maxn]

, s_cnt[maxn]

;//st記錄每乙個數在第幾輪被刪除

//首先我們假設這個序列是單調遞增的,入棧的時候,除了第乙個是不會被刪除的,其他的都是第一輪被刪除的

//然後假設這個序列是遞減的,說明不會有資料被刪除。

//單調棧維護的是乙個 "相鄰的" 遞增的序列

//可以發現當棧中有大於當前資料的時候,此時我們需要更新輪數,把前面一輪能夠刪除的資料都刪除

//表示左邊相鄰的可以資料都有什麼

intmain()

if(!now) cnt =-1

; stk[

++ now]

= a[i]

; s_cnt[now]

= cnt +1;

ans =

max(ans, cnt +1)

;}printf

("%d\n"

, ans)

;return0;

}