1. 程式人生 > >單調佇列(詳細解釋)

單調佇列(詳細解釋)

之前就聽說過單調佇列,這兩天才認真看了一下,後來發現晚上的程式碼各種各樣,比如說指標啊,等等一些高階程式碼(像我這種蒟蒻根本就不怎麼熟練),後來終於發現了一篇容易看得懂的部落格(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);//單減佇列維護最大值 
}


這是我的第一篇部落格,可能不怎麼樣,請見諒!