• 刷题向》POJ2823 单调队列裸题(<不会做,请自裁>系列)


      最近BZOJ炸了,而我的博客上又更新了一些基本知识,所以这里刷一些裸题,用以丰富知识性博客

      POJ2823   滑动的窗口

      这是一道经典的单调队题,我记得我刚学的时候就是用这道题作为单调队列的例题,算一道比较基本的题目

      先贴题目

    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  -1 3
     1 [3  -1  -3] 5  3  6  7  -3 3
     1  3 [-1  -3  5] 3  6  7  -3 5
     1  3  -1 [-3  5  3] 6  7  -3 5
     1  3  -1  -3 [5  3  6] 7  3 6
     1  3  -1  -3  5 [3  6  7] 3 7

    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

      这道题的题目经过思考发现是关于决策的,而状态的转移又有固定的模式,所以是DP。
      那么DP方程是什么捏?
      这个经思考很好得出f[i]=max(f[i],a[k])和g
    [i]=min(g[i],a[k]),k都是从i-k+1到i;
      那么显然的,这个方法不TLE就见鬼了。虽然题目给了你12秒但是你也不能这样胡做
      所以我们考虑更优的解法;
      很容易看出来,我们原方程的每个i的决策与前一个或后一个决策都有k-1个决策重复,而对于每一个决策k的结果,都和i无关,所以我们可以优化这一过程。
      因为当我们更新完第i个位置的最优解的时候,下一个元素的最优解可以用只判断一个元素来更新。
      所以就可以用单调队列了啊(不会的面壁)。
    然后愉快的贴出代码。
     1 #include<cstdio>
     2 #include<cstring>
     3 int quq[1100000],ass,n,k,star,a[1100000],time[1100000];
     4 int main()
     5 {
     6     
     7     scanf("%d%d",&n,&k);
     8     for(int i=1;i<=n;i++)scanf("%d",a+i);
     9     star=1,ass=1;
    10     quq[star]=a[1];
    11     time[ass]=1;
    12     for(int i=2;i<=k;i++)
    13     {
    14         while(a[i]<=quq[ass]&&ass>=star)--ass;
    15         quq[++ass]=a[i];
    16         time[ass]=i;
    17     }
    18     printf("%d ",quq[star]);
    19     for(int i=k+1;i<=n;i++)
    20     {
    21         if(time[star]<=i-k)star++;
    22         while(a[i]<=quq[ass]&&ass>=star)--ass;
    23         quq[++ass]=a[i];
    24         time[ass]=i;
    25         printf("%d ",quq[star]);
    26     }
    27     printf("
    ");
    28     star=1,ass=1;
    29     quq[star]=a[1];
    30     time[ass]=1;
    31     for(int i=2;i<=k;i++)
    32     {
    33         while(a[i]>=quq[ass]&&ass>=star)--ass;
    34         quq[++ass]=a[i];
    35         time[ass]=i;
    36     }
    37     printf("%d ",quq[star]);
    38     for(int i=k+1;i<=n;i++)
    39     {
    40         if(time[star]<=i-k)star++;
    41         while(a[i]>=quq[ass]&&ass>=star)--ass;
    42         quq[++ass]=a[i];
    43         time[ass]=i;
    44         printf("%d ",quq[star]);
    45     }
    46     return 0;
    47 }
    View Code
    
    
    
     
  • 相关阅读:
    地址栏中提交中文参数乱码问题
    拼接html字符串时单引号问题
    细线表格的制作
    盒子模型
    盒子间距离的计算规则:
    正则表达式
    轻便+智能:史上最酷恒温器Nest 2.0!
    医疗的未来,是身体控制大权的争夺战
    而立之年话沧桑
    刘晓明大使在《电讯报》的英文原文
  • 原文地址:https://www.cnblogs.com/PencilWang/p/5936657.html
Copyright © 2020-2023  润新知