詳解--單調隊列 經典滑動窗口問題

單調隊列,即單調的隊列。使用頻率不高,但在有些程序中會有非同尋常的作用。

動態規劃·單調隊列的理解

做動態規劃時常常會見到形如這樣的轉移方程:
f[x] = max or min{g(k) | b[x] <= k < x} + w[x]
(其中b[x]隨x單調不降,即b[1]<=b[2]<=b[3]<=...<=b[n])
(g[k]表示一個和k或f[k]有關的函數,w[x]表示一個和x有關的函數)
這個方程怎樣求解呢?我們注意到這樣一個性質:如果存在兩個數j, k,使得j <= k,而且g(k) <= g(j),則決策j是毫無用處的。因為根據b[x]單調的特性,如果j可以作為合法決策,那么k一定可以作為合法決策,并且k是一個比j要優的決策。因為k比j要優,(注意:在這個經典模型中,“優”是絕對的,是與當前正在計算的狀態無關的),所以,如果把待決策表中的決策按照k排序的話,則g(k)必然是不降的。在此例中決策表即f[x].
這樣,就引導我們使用一個單調隊列來維護決策表。對于每一個狀態f(x)來說,計算過程分為以下幾步:
1、 隊首元素出隊,直到隊首元素在給定的范圍中。
2、 此時,隊首元素就是狀態f(x)的最優決策,
3、 計算g(x),并將其插入到單調隊列的尾部,同時維持隊列的單調性(不斷地出隊,直到隊列單調為止)。
重復上述步驟直到所有的函數值均被計算出來。不難看出這樣的算法均攤時間復雜度是O(1)的。因此求解f(x)的時間復雜度從O(n^2)降到了O(n)。

以下來自某博客+自己補充:

我們從最簡單的問題開始:

給定一個長度為N的整數數列a(i),i=0,1,...,N-1和窗長度k.

要求:

????? f(i) = max{a(i-k+1),a(i-k+2),..., a(i)},i = 0,1,...,N-1

問題的另一種描述就是用一個長度為k的窗在整數數列上移動,求窗里面所包含的數的最大值。

解法一:

很直觀的一種解法,那就是從數列的開頭,將窗放上去,然后找到這最開始的k個數的最大值,然后窗最后移一個單元,繼續找到k個數中的最大值。

這種方法每求一個f(i),都要進行k-1次的比較,復雜度為O(N*k)。

那么有沒有更快一點的算法呢?

解法二:

我們知道,上一種算法有一個地方是重復比較了,就是在找當前的f(i)的時候,i的前面k-1個數其它在算f(i-1)的時候我們就比較過了。那么我們能不能保存上一次的結果呢?當然主要是i的前k-1個數中的最大值了。答案是可以,這就要用到單調遞減隊列。

單調遞減隊列是這么一個隊列,它的頭元素一直是隊列當中的最大值,而且隊列中的值是按照遞減的順序排列的。我們可以從隊列的末尾插入一個元素,可以從隊列的兩端刪除元素。

1.首先看插入元素:為了保證隊列的遞減性,我們在插入元素v的時候,要將隊尾的元素和v比較,如果隊尾的元素不大于v,則刪除隊尾的元素,然后繼續將新的隊尾的元素與v比較,直到隊尾的元素大于v,這個時候我們才將v插入到隊尾。

2.隊尾的刪除剛剛已經說了,那么隊首的元素什么時候刪除呢?由于我們只需要保存i的前k-1個元素中的最大值,所以當隊首的元素的索引或下標小于i-k+1的時候,就說明隊首的元素對于求f(i)已經沒有意義了,因為它已經不在窗里面了。所以當index[隊首元素]<i-k+1時,將隊首元素刪除。

(補充:隊列中的元素主要包括了兩個性質:大小--決定它是否影響f[i]的求值,時效性(刪除隊頭使用)--數組下標決定它是否已經離開了滑動窗口,不在影響f[i]了,刪除隊尾時,是新入隊的時效性>已在隊中的元素了,如果隊尾的取值不如新入隊的元素的值優的話,那么就可以刪除隊尾了。)

從上面的介紹當中,我們知道,單調隊列與隊列唯一的不同就在于它不僅要保存元素的值,而且要保存元素的索引(當然在實際應用中我們可以只需要保存索引,而通過索引間接找到當前索引的值)。

為了讓讀者更明白一點,我舉個簡單的例子。

假設數列為:8,7,12,5,16,9,17,2,4,6.N=10,k=3.

那么我們構造一個長度為3的單調遞減隊列:

首先,那8和它的索引0放入隊列中,我們用(8,0)表示,每一步插入元素時隊列中的元素如下:

0:插入8,隊列為:(8,0)

1:插入7,隊列為:(8,0),(7,1)

2:插入12,隊列為:(12,2)

3:插入5,隊列為:(12,2),(5,3)

4:插入16,隊列為:(16,4)

5:插入9,隊列為:(16,4),(9,5)

。。。。依此類推

那么f(i)就是第i步時隊列當中的首元素:8,8,12,12,16,16,。。。

例題:POJ 2823 滑動窗口

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Sliding Window

Time Limit:?12000MS?Memory Limit:?65536K
Total Submissions:?54158?Accepted:?15543
Case Time Limit:?5000MS

Description

An array of size?n?≤ 106?is given to you. There is a sliding window of size?k?which is moving from the very left of the array to the very right. You can only see the?k?numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:?
The array is?[1?3?-1?-3?5?3?6?7], and?k?is 3.
Window positionMinimum valueMaximum value
[1??3??-1]?-3??5??3??6??7?-13
?1?[3??-1??-3]?5??3??6??7?-33
?1??3?[-1??-3??5]?3??6??7?-35
?1??3??-1?[-3??5??3]?6??7?-35
?1??3??-1??-3?[5??3??6]?7?36
?1??3??-1??-3??5?[3??6??7]37

Your task is to determine the maximum and minimum values in the sliding window at each position.?

Input

The input consists of two lines. The first line contains two integers?n?and?k?which are the lengths of the array and the sliding window. There are?n?integers in the second line.?

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.?

Sample Input

8 3
1 3 -1 -3 5 3 6 7

Sample Output

-1 -3 -3 -3 3 3
3 3 5 5 6 7
 1 #define N 1000005
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 #include<cstdio>
 6 struct Pai{
 7     int val,pos;
 8 };
 9 Pai minque[N],maxque[N];
10 int minans[N],maxans[N],minhead,maxhead,mintail,maxtail,cur=0;
11 int n,k;
12 int main()
13 {
14     scanf("%d%d",&n,&k);
15     int num;
16     minque[0].val=(1<<31)-1;
17     maxque[0].val=(1<<31)-1;
18     maxque[0].val*=-1;
19 /*使用最大值最小值,為了讓que[0]會被后來的元素占用,防止因為que[0]=0的這個數,代替了本來的最大值或者最小值,所以一開始時會有mintail<0,但是之后馬上就++mintail了,沒有訪問數組,所以不會有越界情況的。*/
20     for(int i=1;i<=k;++i)
21     {
22         scanf("%d",&num);
23         while(minhead<=mintail&&minque[mintail].val>=num) mintail--;
24         minque[++mintail].val=num;
25         minque[mintail].pos=i;
26         while(maxhead<=maxtail&&maxque[maxtail].val<=num) maxtail--;
27         maxque[++maxtail].val=num;
28         maxque[maxtail].pos=i;
29     }
30     for(int i=k+1;i<=n;++i)
31     {
32         minans[++cur]=minque[minhead].val;
33         maxans[cur]=maxque[maxhead].val;
34         scanf("%d",&num);
35         
36         while(minhead<=mintail&&i-minque[minhead].pos>=k)++minhead;
37         while(minhead<=mintail&&minque[mintail].val>=num) mintail--;
38         minque[++mintail].val=num;
39         minque[mintail].pos=i;
40         
41         while(maxhead<=maxtail&&i-maxque[maxhead].pos>=k)++maxhead;
42         while(maxhead<=maxtail&&maxque[maxtail].val<=num) maxtail--;
43         maxque[++maxtail].val=num;
44         maxque[maxtail].pos=i;
45     }
46     minans[++cur]=minque[minhead].val;
47     maxans[cur]=maxque[maxhead].val;
48     for(int i=1;i<=cur;++i)
49       printf("%d ",minans[i]);
50     printf("\n");
51     for(int i=1;i<=cur;++i)
52       printf("%d ",maxans[i]);
53     return 0;
54 }

?

轉載于:https://www.cnblogs.com/c1299401227/p/5774133.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/395328.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395328.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395328.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java Persistence with MyBatis 小結2

MyBatis 最關鍵的組成部分是 SqlSessionFactory&#xff0c;我們可以從中獲取 SqlSession&#xff0c;并執行映射的 SQL 語句。SqlSessionFactory 對象可以通過基于 XML 的配置信息或者 Java API 創建。 1 mybatis環境&#xff0c;environments 配置默認的數據庫環境 MyBatis 支…

《計算機應用基礎》18春作業,【北語網院】18春《計算機應用基礎》作業_2.pdf...

謀學網【北京語言大學】 18 春《計算機應用基礎》作業 _2試卷總分 :100 得分 :100第 1 題, 操作系統是 ___ 的接口。A、用戶與軟件B、系統軟件與應用軟件C、主機與外設D、用戶與計算機第 2 題, 計算機配置的內存的容量為 128MB或 128MB以上&#xff0c;其中的 128MB是指 __ 。A…

freeCodeCamp納什維爾十月聚會回顧

by Seth Alexander塞斯亞歷山大(Seth Alexander) 納什維爾的美好時光&#xff1a;十月免費CodeCamp聚會的回顧 (Good times in Nashville: a recap of our October freeCodeCamp Meetup) On Saturday, October 7, we had our monthly freeCodeCamp Nashville meetup at Nashvi…

c#時分秒毫秒微妙_你真的清楚DateTime in C#嗎?

DateTime&#xff0c;就是一個世界的大融合。日期和時間&#xff0c;在我們開發中非常重要。DateTime在C#中&#xff0c;專門用來表達和處理日期和時間。本文算是多年使用DateTime的一個總結&#xff0c;包括DateTime對象的整體應用&#xff0c;以及如何處理不同的區域、時區、…

(HY000): Cannot modify @@session.sql_log_bin inside a transaction

昨天&#xff0c;線上發生一例(HY000): Cannot modify session.sql_log_bin inside a transaction代碼缺少顯示的start transaction控制。。轉載于:https://www.cnblogs.com/zhjh256/p/5775390.html

解決Eclipse的Team菜單中沒有SVN選項的問題

剛開始自己拿一個項目&#xff0c;手練一下發覺在Eclipse的Team找不到SVN倉庫&#xff0c;看了一下才發覺使用SVN向SVN服務器上傳代碼&#xff0c;但Eclipse默認情況下卻沒有SVN選項&#xff0c;剛開始也是這樣的 默認只有GIT&#xff0c;如下圖所示 想要解決這些問題&#xff…

怎么用計算機怎么截屏,電腦怎么截圖 這幾個方法操作簡便且實用

在日常的生活當中我們在使用電腦的時候經常會碰一些喜歡的文字、圖片無法保存的情況&#xff0c;面對這樣的狀況&#xff0c;我們想要將這些東西保留下來那就會用到電腦截圖了&#xff0c;這個方法可以很輕松的就將我們無視無法保存的情況而將這些東西給保留下來。那么電腦要怎…

python socket 多人聊天室

參考來源&#xff08;其實我從上面復制了一點&#xff09;&#xff1a;Python 的 Socket 編程教程 http://www.oschina.net/question/12_76126Python線程指南 http://www.open-open.com/lib/view/open1345476194313.htmlPython Socket文檔 https://docs.python.org/3/library/…

json數據轉換成表格_電子表格會讓您失望嗎? 將行數據轉換為JSON樹很容易。

json數據轉換成表格Like many of you, I often have to take the result of SQL queries and convert the rowsets to JSON data objects. Sometimes I have to do the same with CSV files from spreadsheets. The transformation process can be a hassle, though anyone can…

mxm智能教育機器人無法智能對話_零代碼使用騰訊TBP打造智能對話機器人

點擊觀看大咖分享心疼你獨自一人承擔生活的苦難&#xff0c;寂寞夜里陪伴你的只剩無人傾訴的壓抑和無處安放的焦慮。養個寵物&#xff0c;它卻不能get到你的“寵言寵語”。找個伴侶&#xff0c;還要浪費吵架的時間和精力。回到家里&#xff0c;只能浸泡在“循環嘮叨式“母愛的沐…

MyGeneration代碼生成工具

使用MyGeneration 生成代碼&#xff1a;轉自http://www.cnblogs.com/jack-liang/archive/2011/08/18/2144066.html我們經常用數據訪問層和業務邏輯層&#xff0c;用MyGeneration就可以自動生成這些代碼&#xff0c;我們可以不用手動寫代碼了。比如數據訪問層&#xff0c;我們需…

數據庫部分重點內容回顧

1.什么是聚集索引? 樹形結構將數據組織和存儲起來,起到加速查詢的效果 2.主鍵索引怎么添加? (1)聚集索引(主鍵索引)的添加方式,創建時添加 方式一: Create table t1( id int primary key, ) 方式二: Create table t1( Id int, Primary key(id) ) (2)唯一索引創建時添加: 方式…

keytool 錯誤: java.io.IOException: Keystore was tampered with, or password was incorrect

1.這里需要輸入的密碼不是證書的密碼執行keytool -import -keystore - file 這個命令提示需要輸入密碼進入jdk的bin目錄&#xff0c;執行以下腳本&#xff0c;keytool -import -alias saltapi -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre…

怎么更換鎖定計算機的圖片,Win10系統下怎樣對鎖定界面的背景圖片進行更換

用戶在喚醒睡眠狀態的win10系統時&#xff0c;最先看到就是鎖定界面。在界面中&#xff0c;一般有時間日期、星期幾&#xff0c;及默認的背景圖片。那么&#xff0c;win10系統鎖定界面中的背景圖片可以修改嗎&#xff1f;下面&#xff0c;小編就給大家分享Win10系統更換鎖定界面…

輸電線路巡檢機器人PPT_“高空大師”來了!架空輸電線路智能巡檢機器人在寧波投運...

“鄞州區220千伏天田4480線一切正常……”17日上午&#xff0c;隨著一臺智能巡檢機器人穩穩地停靠在鐵塔邊&#xff0c;標志著我省首臺架空輸電線路智能巡檢機器人在寧波率先投入運行&#xff0c;為電網安全運行請來了一位“高空大師”。近年來&#xff0c;無人機代替電力工人巡…

HDU 6325 Problem G. Interstellar Travel(凸包)

題意: 給你n個點,第一個點一定是(0,0)&#xff0c;最后一個點縱坐標yn一定是0&#xff0c;中間的點的橫坐標一定都是在(0,xn)之間的 然后從第一個點開始飛行&#xff0c;每次飛到下一個點j&#xff0c;你花費的價值就是xi*yj-xj*yi&#xff0c;并且這里每一次飛行必須滿足xi<…

UIView封裝動畫--iOS利用系統提供方法來做關鍵幀動畫

iOS利用系統提供方法來做關鍵幀動畫 ios7以后才有用。 /*關鍵幀動畫options:UIViewKeyframeAnimationOptions類型*/[UIView animateKeyframesWithDuration:5.0 delay:0 options: UIViewAnimationOptionCurveLinear| UIViewAnimationOptionCurveLinear animations:^{//第二個關鍵…

JavaScript —從回調到異步/等待

JavaScript is synchronous. This means that it will execute your code block by order after hoisting. Before the code executes, var and function declarations are “hoisted” to the top of their scope.JavaScript是同步的。 這意味著它將在提升后按順序執行代碼塊。…

關于解決工作中的自動化環境搭建的解決方案(序)

時間&#xff1a;2015~2017 之前的自動化搭建平臺&#xff1a;robotest 安裝工具&#xff1a;jdk1.8,robotest 這種工具反正超級好用&#xff0c;華為方搞得工具&#xff0c;前臺操作超級傻瓜。會點xpatch&#xff0c;一些東西根本不在話下。但是坑爹的就是&#xff0c;出了外包…

xshell安裝mysql步驟_mysql主從復制

前期提要&#xff1a;三年前雙11買的阿里云今年到期了&#xff0c;win2012的&#xff0c;上面mysql數據庫里記著自己的一些記賬數據&#xff0c;上一年雙11買了騰訊云的&#xff0c;centos7.7, 想學學MYSQL的復制功能&#xff0c;今天趁著無BUG可擼&#xff0c;試著配置了一下&…