【データ構造学習】単調キュー

単調なキュー、つまりコンパレーターに関連する内部要素の順序付けされたキューは、シーケンスの連続した間隔で最大値/最小値を簡単にクエリできます

また、状態遷移時の決定を最適化して、時間の複雑さを軽減することもできます。(まあ、この文章はOI-Wikiで言われています。konjacqwqはdpを最適化する方法がわからないからです)

 

たとえば、長さnの数列の連続する各k数の最小数を知りたいとします。

激しく解く場合、トラバーサルは1からn-k + 1、複雑度O(n * k)であり、各サブシーケンスの値は、比較的遅い他の値と比較する必要があります。

この問題では、減少する単調なキューを維持し、キュー内の数値範囲がkを超えないように注意することができます

 

メンテナンス方法:

新しい番号がシーケンスで読み取られるたびに、その番号とチームの最後の番号との関係が比較されます

1.番号がチームの最後の番号より大きい場合は、チームに参加します。

2.サマリーがチームの終わりよりも小さい場合、チームの終わりはチームの外にあり、その数はチームの終わりと再度比較されます。

 

チームに入った後、現在のチームの先頭と末尾の番号に含まれる番号範囲がkを超えているかどうかを確認します

超過した場合、チームは初めてチームを離れます。

 

cin >> t;
while(!dq.empty()&& dq.back()> t)
    dq.pop_back()、no.pop_back(); 
dq.push_back(t)、no.push_back(i); 
while(no.back()-no.front()> = k)
    dq.pop_front()、no.pop_front();

//これは、dequeをコンテナーメンテナンスの単調なキューとして使用しています。また、dequeもありません。dq内の番号の対応する番号(添え字)を維持します

 この方法で維持されるキューの先頭要素は、常にすべてのk要素の最小です

O(1)を取り出すことができ、各番号は最大で1回デキューおよびエンキューできます。キューを維持する時間の複雑さはO(n)のみです。

おすすめ

転載: www.cnblogs.com/leafsblogowo/p/12687225.html