# 中電會六月主題課程--進階動態規劃 --- 點名 回饋表單 --- ## 單調棧(Monotonic stack) ---- ![](https://media.geeksforgeeks.org/wp-content/cdn-uploads/20221219100314/stack.drawio2.png) ---- [Nearest Smaller Values](https://cses.fi/problemset/task/1645) ---- ### 觀察 ![image](https://hackmd.io/_uploads/HyYfCMyHA.png) 有一些數字不會是答案 例如位置1的5,因為他右邊有一個1。當右邊某個數字(假設$x$)往左邊掃時,他一定會先掃到1才掃到5,此時5永遠不可能是答案,因為若5比$x$小,則1也會比$x$小。 ---- ![image](https://hackmd.io/_uploads/SkFLVVkHA.png) ---- $$ \begin{aligned} &\text{for all } (i,j) \text{ where }i<j<n \text{ ,} \\ &\text{if } a_i\geq a_j \text{ ,}\\ &i \text{ is not the answer for any } k>j \end{aligned} $$ ---- 把不可能的都刪掉後,最後剩下的一定是**嚴格遞增**的 ---- ### 實作 ![image](https://hackmd.io/_uploads/HyheON1B0.png) ---- ```cpp= stack<int> st; st.push(0); vector<int> v(n+1); v[0]=-1; for(int i=0;i<n;i++){ int a; cin>>a; v[i+1]=a; } for(int i=1;i<n+1;i++){ while(v[st.top()]>=v[i]) st.pop(); cout<<st.top()<<" "; st.push(i); } ``` ---- ### 延伸 [Advertisement](https://cses.fi/problemset/task/1142) [Maximum Building I](https://cses.fi/problemset/task/1147) --- ## 單調佇列(Monotonic queue) 我都叫他單調隊列 ---- 實作上會使用deque ![](https://media.geeksforgeeks.org/wp-content/uploads/anod.png) 就只是變兩頭都可以操作而已 ---- [a146. Sliding Window](https://zerojudge.tw/ShowProblem?problemid=a146) ---- ### 直覺解法 維護一個multiset,每次輸出最大/小的,再刪掉過期的並加入新的 $\text{O}(n\log n)$ ---- ### 觀察 ![image](https://hackmd.io/_uploads/BJZKFBkBA.png) ---- ### 延伸 [Maximum Subarray Sum II](https://cses.fi/problemset/task/1644/) 有限個數的多重背包問題 --- ## [斜率優化](https://hackmd.io/@tmting39/ByGhMYmra)
{"title":"中電會六月主題課程–進階動態規劃","contributors":"[{\"id\":\"98ae9bd8-05ef-4e0a-b451-d465f67f398f\",\"add\":1656,\"del\":59}]","description":"點名回饋表單"}
    250 views