每日一题:奶牛排队

题目链接:https://www.luogu.com.cn/problem/P6510
题目描述:
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛A是最矮的,最右边的B是最高的,且B奶牛高于A奶牛。中间如果存在奶牛,则身高不能和A,B奶牛相同。问这样的奶牛最多会有多少头?

输入:第一行一个正整数N表示奶牛的头数。

输出:一行一个整数,表示最多奶牛数。

解题思路:我们要找到从后向前数第二个后缀最大值的位置k,A一定在该位置的右侧。并且只要A在k右侧,A是当前序列的后缀最小值,那么A就是一个正确的左端点。

具体代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define NO cout<<"NO"<<endl;
#define YES cout<<"YES"<<endl;
ll NUM=1e9+2;

const int maxn = 100005;

int n, ans, tx, tn;
int a[maxn], sx[maxn], sn[maxn];

int main() {
    scanf("%d", &n);
    for (int i=1;i<=n;++i) scanf("%d",a+i);
    for (int i=1;i<=n;++i) {
        while (tn && a[sn[tn]] >= a[i]) --tn;
        ////保持 sn 数组的元素所对应的 a 数组元素呈现单调递减的性质
        while (tx && a[sx[tx]] < a[i]) --tx;
        ////保持 sx 数组的元素所对应的 a 数组元素呈现单调递增的性质
        int k = upper_bound(sn+1, sn+1+tn, sx[tx])-sn;
        ////在[sn+1,sn+1+tn)区间中查找第一个大于 sx[tx] 的元素并计算长度
        if (k!=(tn+1)) {
            ans=max(ans, i - sn[k] + 1);
            ////就更新 ans 成为最大值;
        }
        sn[++tn]=i;
        //// 将当前元素索引存储到 sn 数组中
        sx[++tx]=i;
    }//// 将当前元素索引存储到 sx 数组中
    printf("%d\n", ans);
    return 0;
}

posted on   神奇猫猫侠  阅读(20)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示