Sliding Window

Posted JZYshuraK_彧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sliding Window相关的知识,希望对你有一定的参考价值。

poj2823 Sliding Window

    题目大意:给你一个n个数的序列,有一个长度固定的窗口,求出两个数列,分别是窗口从左滑到右,窗口内的最小值和最大值,分两行输出。

    注释:n<=$10^6$,内存<=64.

      想法:这内存是真恶心啊,正常的ST算法过不去,想到线段树,......咳咳,虽然这道题可以用单调队列和线段树没有什么障碍的A掉,但是今天我们仍然用ST维护RMQ来解决。首先,我们对内存有一定的限制,但是我们有一个极好的条件,那就是窗口的大小是固定的。所以,不难发现,我们所用到的f[i][j]数组只用到了最后一维,那么,我们想办法压维。压维最根本的是可否可行在于动态规划更新时是否有后效性。所以,我们就看一看。首先,我们显然知道,更新一个f的值所用到的,一定有一个是它自己,还有一个就是往后$2^{j-1}$所代表的值,不难发现,这两个下表都不小于i。所以,我们在从左向右松弛1-n时,所用到的下标都是没有被这一轮更新的,也就是说,是没有后效性的,故此,我们压维是可以的。所以,这道题就A掉了。

    在此,我们有一个东西,就是log数组是不需要占用一个数组的内存的,我们发现,我们窗口固定时,log所提取的数也是固定的,那么我们就可以在预处理时顺便将log的值附好,即可。

    最后,附上丑陋的代码... ...

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #define N 1000010
 5 using namespace std;
 6 int a[N];
 7 int f[N],g[N];
 8 int main()
 9 {
10     int n,len;
11     int maxlog;
12     while(~scanf("%d%d",&n,&len))
13     {
14         // memset(f,0,sizeof(f));
15         // memset(g,0,sizeof(g));
16         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
17         for(int i=1;i<=n;i++)//初始化 
18         {
19             f[i]=a[i];
20             g[i]=a[i];
21         }
22         maxlog=0;//这点贼重要,我们发现如果len==1,maxlog没有值??! 
23         for(int i=1;(1<<i)<=len;i++)
24         {
25             maxlog=i;
26             for(int j=1;j+(1<<i)-1<=n;j++)
27             {
28                 f[j]=max(f[j],f[j+(1<<(i-1))]);
29                 g[j]=min(g[j],g[j+(1<<(i-1))]);
30             }
31         }
32         // cout<<"maxlog="<<maxlog<<endl;
33         // for(int i=1;i+(1<<maxlog)-1<=n;i++)
34         // {
35             // cout<<"f["<<i<<"]="<<f[i]<<endl;
36         // }
37         for(int i=1;i<=n-len+1;i++)
38         {
39             printf("%d ",min(g[i],g[i+len-(1<<maxlog)]));
40         }
41         printf("\n");//别忘记分行 
42         for(int i=1;i<=n-len+1;i++)
43         {
44             printf("%d ",max(f[i],f[i+len-(1<<maxlog)]));
45         }
46         printf("\n");
47     }
48 }

    小结:RMQ的点还有很多,还是那句话,倍增的想法的重要性要超过这个算法本身。

      错误:1.maxlog的初始化,极其重要。

         2.在初始化时,注意端点的位置。

以上是关于Sliding Window的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2823 Sliding Window(单调队列)

Sliding Window Maximum

480. Sliding Window Median

239. Sliding Window Maximum

POJ 2823 Sliding Window 题解

239. Sliding Window Maximum