1035: 最大子序列(单调队列小改)

今天上午学了一波单调队列,然后学完单调队列后领悟到了一点小思路,hhh,然后我就在单调队列的基础上进行了改进,仅仅限制了进入队列中的元素个数,然后按照单调性,进行不断去除,然后输出个数即可。

注意1:单调队列,单调栈写这种题一般存的是坐标,这样才能进行新老元素的更换
注意2:这题我用线段树也A了,但是注意这道题给了1e6的数据范围,因为题目水了,后台数据只有1e5,所以我们可以用线段树过,但是如果数据是1e6,线段树需要开4倍空间,所以过不了这道题,这题给定内存限制小于1e6*4

我们来看一下1e5数据下,单调队列修改的代码和线段树的代码所用的内存大小:
单调队列:
在这里插入图片描述
线段树:
在这里插入图片描述

这就是在解决特定问题上单调队列或者单调栈和线段树的差别,所以多学习点新知识才会进步。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int q[maxn],a[maxn];
int n,k;
void solv()
{
    int head=0,tail=-1,id;
    bool fla=true;
    for(int i=0; i<n; i++)
    {
        while(head<=tail&&n-q[tail]-1>=k&&a[q[tail]]<a[i]&&fla)
            tail--;
        if(n-q[tail]-1>=k&&fla)
            q[++tail]=i;
        else
        {
            fla=false;
            int x=q[tail];
            while((n-x-1)>(k-tail-1)&&a[q[tail]]<a[i])
                tail--;
            q[++tail]=i;
        }
    }
    for(int i=0; i<k; i++)
    {
        if(i==k-1)
            cout<<a[q[i]]<<endl;
        else
            cout<<a[q[i]]<<' ';
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    while(cin>>n>>k)
    {
        for(int i=0; i<n; i++)
            cin>>a[i];
        solv();
    }
}
发布了254 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yangzijiangac/article/details/104860215