• 单调队列


    分析

       我们要查询区间最值而且区间长度是固定的

       这是我们才能用单调队列优化

     

    代码

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstdio>
     4 using namespace std;
     5 int a[2000001],f[2000010],num[2000010],q[2000010];
     6 int main ()
     7 {
     8     int n,k;
     9     cin>>n>>k;
    10     for (int i=1;i<=n;i++)
    11        scanf("%d",&a[i]);
    12     int head=1,tail=0;
    13     for (int i=1;i<=n-1;i++)
    14     {
    15         while (num[head]<i-k+1&&head<=tail) head++;
    16         while (a[i]<=q[tail]&&head<=tail) tail--;
    17         num[++tail]=i; q[tail]=a[i];
    18         f[i]=q[head];
    19     }
    20     cout<<0<<endl;
    21     for (int i=1;i<=n-1;i++)
    22       printf("%d
    ",f[i]);
    23 }

    分析

         我们要求一个数列中连续m项的最大值

         首先显然是要求一个前缀和

         然后我们需要用一个单调队列来维护我s[i-1...k] 的最小值

     1 #include<iostream>
     2 #include<queue>
     3 #include<cstdio>
     4 using namespace std;
     5 int a[2000001],f[2000010],num[2000010],q[2000010],s[2000010];
     6 int main ()
     7 {
     8     int n,k;
     9     cin>>n>>k;
    10     for (int i=1;i<=n;i++)
    11        scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
    12     int ans=-1e9;
    13     int head=1,tail=1; q[tail]=0; num[tail]=0;
    14     for (int i=1;i<=n;i++)
    15     {
    16         while (num[head]<i-k&&head<=tail) head++;
    17         ans=max(ans,s[i]-q[head]);
    18         while (s[i]<=q[tail]&&head<=tail) tail--;
    19         num[++tail]=i; q[tail]=s[i];
    20     }
    21     cout<<ans;
    22 }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    PPT1 例1
    皇宫看守 树形DP
    没有上司的晚会 树形DP
    将功补过 树形DP
    战略游戏 树形DP
    选课 树形DP
    二叉苹果树 树形DP
    GDOI2016总结
    加分二叉树 树形DP
    [注意]未做的题(最短路)
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11193599.html
Copyright © 2020-2023  润新知