單調佇列(詳細解釋)
阿新 • • 發佈:2018-12-24
之前就聽說過單調佇列,這兩天才認真看了一下,後來發現晚上的程式碼各種各樣,比如說指標啊,等等一些高階程式碼(像我這種蒟蒻根本就不怎麼熟練),後來終於發現了一篇容易看得懂的部落格(http://blog.csdn.net/acvay/article/details/46772771)然後加上了一些自己的理解詳細解釋,便寫出來供大家參考,後面註釋是自己的理解,語文不好,有可能表達意思不清晰,或者表達有誤,請見諒。
感謝博主 知足o 因為在下不知道怎麼通過部落格通知您老,於是便未經您老允許轉載,請見諒,畢竟還是個高中生。
其實,對於學演算法,還是要加上題目去學,才能更容易理解。在之前學線段樹,我沒看題目直接學,學到最後都不知道在幹什麼,直到在COODVS上看了幾個線段樹練習的題目才知道線段樹到底要幹什麼,於是學單調佇列我也是通過POJ上的一個題目更進一步理解單調佇列到底是幹什麼的,能用來幹什麼。
附題目:http://poj.org/problem?id=2823
程式碼:
#include<iostream> #include<cstdio> #define pd (!x&&f[tail-1]>a[i])||(x&&f[tail-1]<a[i]) using namespace std; int n,k,head,tail; int a[1000001],f[1000001],t[1000001]; void getmaxmin(int x) { head=tail=0; for(int i=0;i<n;i++) { while(head<tail&&(pd))tail--; //求最小值那麼就從尾部開始刪除比他大的值 //求最大值那麼就從尾部刪除比他小的值 f[tail]=a[i]; t[tail]=i;//記錄當前認為最小值的下標(位置) tail++; while(t[head]<=i-k)head++; //當前i的位置向左移滑框的距離,其中不包括當前最小值的位置 //保證隊首元素在滑窗之內,不在滑窗內那麼就說明滑窗已經移動到後面了,那麼這個時候,就要把首指標右移,當前首指標指的值不在新的滑窗範圍之內 if(i>k-2) //自己用樣例代一代發現滿足這個神奇的現象 //需要輸出了,大概就是滿足了更新新的值,要輸出這段k中的最大或最小值 printf("%d%c",f[head],i == n - 1 ? '\n' : ' ');//當輸出完了最小值那麼就要換行 } } int main() { scanf("%d%d",&n,&k); for(int i=0;i<n;i++)scanf("%d",&a[i]); getmaxmin(0);//單增佇列維護最小值 getmaxmin(1);//單減佇列維護最大值 }
這是我的第一篇部落格,可能不怎麼樣,請見諒!