G - Mike and Feet(单调栈)

本文介绍使用单调栈高效计算不同长度区间内的最小值,并通过一个具体实例详细展示了如何找到每个区间的最小值,进而得到这些最小值中的最大值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击打开链接

讲单调栈的博文 点击打开链接

给你一个区间里的每个数,求区间大小分别为1,2,3,4.....每个小区间的数中最小值,再求这些最小值中的最大值

用单调栈可以在on内算出每个数的左边右边第一个小于这个数的值的位置

然后int len=r[i]-l[i]+1,就可以算出区间长度为len的最小值

考虑到有些区间长度可能并不会出现,根据res[i-1]=max(res[i-1],res[i])

即区间长度为i-1的最小值的最大值至少为res[i]

所以最后需要在遍历一遍,补齐res数组

 

#include<iostream>
#include<stdio.h>
#include<stack>
#define N 200005
using namespace std;

int a[N],l[N],r[N],res[N];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    stack<int> ss;
    for(int i=1;i<=n;i++)
    {
        while(!ss.empty() && a[ss.top()]>=a[i])
            ss.pop();
        if(ss.empty())
            l[i]=1;
        else
            l[i]=ss.top()+1;//记录第i位为最小值的左端点
        ss.push(i); //压进栈的不是数,而是这个数的位置
    }
    while(!ss.empty())
        ss.pop();
    for(int i=n;i>0;i--)
    {
        while(!ss.empty() && a[ss.top()]>=a[i])
            ss.pop();
        if(ss.empty())
            r[i]=n;
        else
            r[i]=ss.top()-1;//记录第i位为最小值的右端点
        ss.push(i);
    }
    for(int i=1;i<=n;i++)
    {
        int len=r[i]-l[i]+1;
        res[len]=max(res[len],a[i]);
    }
    for(int i=n-1;i>=1;i--)
    {
        res[i]=max(res[i],res[i+1]);
    }
     for(int i=1;i<=n;i++){
        printf("%d",res[i]);
        if(i==n) printf("\n");
        else printf(" ");
    }
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值