AcWing 134 雙端佇列

2021-09-21 18:49:28 字數 1458 閱讀 3347

題目描述:

達達現在碰到了乙個棘手的問題,有n個整數需要排序。

達達手頭能用的工具就是若干個雙端佇列。她從1到n需要依次處理這n個數,對於每個數,達達能做以下兩件事:

1.新建乙個雙端佇列,並將當前數作為這個佇列中的唯一的數;

2.將當前數放入已有的佇列的頭之前或者尾之後。

對所有的數處理完成之後,達達將這些佇列按一定的順序連線起來後就可以得到乙個非降的序列。

請你求出最少需要多少個雙端序列。

輸入格式

第一行輸入整數n,代表整數的個數。接下來n行,每行包括乙個整數di,代表所需處理的整數。

輸出格式

輸出乙個整數,代表最少需要的雙端佇列數。

資料範圍

1≤n≤200000

輸入樣例:

636

0963

輸出樣例:

2
分析:

我們知道,要想將幾個雙端佇列直接拼成乙個單調的序列,則這幾個雙端佇列內部的順序也一定是單調的,並且每個佇列都是最後排好序的序列中的某一段連續的序列。想象一下任乙個雙端佇列內部元素入隊的順序,一般情況下,下標最小的元素首先入隊,之**隊的元素若比它小就插入到它前面,比它大就插入到它後面,則對於最終的任乙個有序的佇列,其中元素的下標一定是先遞減再遞增,也就是被稱為滿足單谷性質的序列。

知道這個性質有什麼用呢?就是我們知道了最終有序序列中某一段要想僅占用乙個佇列,當且僅當他們的下標會滿足這樣的單谷性質,於是本題便由求最小的雙端佇列數轉化為了求單谷序列最小的數目。值得注意的是,若原序列含有相同元素,則最後有序序列對應下標的順序就不唯一了,我們只需要找到其中單谷序列最小的那個順序即可。比如樣例中的360963,排序後為033669,下標的一種順序為205143,這樣(20)(51)(43)便是三個單谷了,稍微調整下重複元素下標的順序,使得下標排列為205413,(205)(413)便只需要兩個佇列了,可見,重複元素順序的處理對最終結果尤為重要。

為了使得單谷序列最少,我們盡可能的使得資料上公升下降趨勢改變的越少越好,比如下標34的元素值相等,從下標為5的元素往後遍歷,必然會有遞減,543,則只是遞減,534則有了波動。所以對於重複元素的下標,如果此時是上公升趨勢,後面重複元素最小的下標大於之前元素的下標,則繼續上公升趨勢,否則要增加佇列,改趨勢為下降。若是下降趨勢也是同理,重複元素最大的下標小於前面的下標,則繼續下降,否則改趨勢為上公升。

#include #include using namespace std;

const int maxn = 200005;

paira[maxn];

int main()

sort(a,a + n);

int pre = maxn,dir = -1;

for(int i = 0;i < n;)

}else

}i = j;

}cout

}

acwing 134 雙端佇列

把乙個陣列排序,必須使用雙端佇列,必須從1到n依次處理,問最少要多少個雙端佇列。和歸併一樣,在乙個佇列裡,按照陣列下標從1到n,把值大的往後扔,小的往前扔。這樣乙個佇列裡面,從前往後,下標肯定是先減後增的。並且 這些佇列也是有序的,也就是說,除了第乙個佇列,乙個佇列的最小值應該是比乙個佇列的最大值大...

雙端佇列 Acwing 134 雙端佇列

達達現在碰到了乙個棘手的問題,有n個整數需要排序。達達手頭能用的工具就是若干個雙端佇列。她從1到n需要依次處理這n個數,對於每個數,達達能做以下兩件事 1 新建乙個雙端佇列,並將當前數作為這個佇列中的唯一的數 2 將當前數放入已有的佇列的頭之前或者尾之後。對所有的數處理完成之後,達達將這些佇列按一定...

CH134 雙端佇列 題解報告

題目傳送門 題目大意 用若干個雙端佇列給 n 個整數排序,依次處理這 n 個數,對於每個數 a i 可以進行兩種操作 1.新建乙個雙端佇列,並將 a i 作為這個佇列中唯一的數 2.把 a i 從已有佇列的隊頭或隊尾入隊 對所有的數處理完後,要求這些佇列能夠按照一定的順序連線起來,得到乙個非降的長度...