奶牛排队(题解)

奶牛排队
【问题描述】
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛A 是最矮的,最右
边的B 是最高的,且B 高于A 奶牛,且中间如果存在奶牛,则身高不能和A、B 奶牛相同,
问这样的一些奶牛最多会有多少头。
从左到右给出奶牛的身高,请告诉它们符合条件的最多的奶牛数(答案可能是零、二,
但不会是一)。
【输入格式】
第一行一个数N(2<=N<=100000),表示奶牛的头数。
接下来N 个数, 每行一个数, 从上到下表示从左到右奶牛的身高( 1<= 身高
<=maxlongint)。
【输出格式】
一行,表示最多奶牛数。
【输入样例】Tahort.in
5
1
2
3
4
1
【输出样例】Tahort.out
4
【样例解析】
取第1 头到第4 头奶牛,满足条件且为最多。

乍一看,像是最长上升子串,但是,但是,但是,这道题中间的数不要求必须是上升的,所以只要保证是第一个数比最后一个数小就行。

结合代码解释一下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
#define zxy(i , a , b)    for(ll i = a ; i <= b ; i ++)
#define zxyzxy(i , a , b)    for(ll i = a ; i < b ; i ++)
#define yxz(i , a , b)    for(ll i = a ; i >= b ; i --)
#define yxzyxz(i , a , b)    for(ll i = a ; i > b ; i --)
#define N 100010
typedef long long ll;
int read()
{
    int ans = 0;
    char ch = getchar(),last = ' ';
    while(ch < '0' || ch > '9')
        last = ch , ch = getchar();
    while(ch >= '0' && ch <= '9')
        ans = ans * 10 + ch - '0' , ch = getchar();
    if(last == '-')
        ans = -ans;
    return ans;
}
void put(int x)
{
    if(x < 0)
    {
        putchar('-');
        x = -x;
    }
    if(x == 0)
    {
        putchar('0');
        return;
    }
    int q[100] , nn = 0;
    while(x)
        q[++ nn] = x % 10 , x /= 10;
    while(nn)
        putchar('0' + q[nn]), --nn;
}
int x[N], h[N];
int n, ans;
int main()
{
    //freopen("tahort.in", "r", stdin);
    //freopen("tahort.out", "w", stdout);
    n = read();
    zxy(i , 1 , n)
        x[i] = read();
    zxy(i , 1 , n)
    {
        int num = i - 1, j = i - 1;
        while(j)
        {
            if(h[j] >= h[i]) 
                break;
            if(h[x[j] + 1] < h[num + 1]) 
                num = x[j];
            j = x[j];
        }
        x[i] = num;
        ans = max(ans,i-num);
    }
    if(ans == 1) 
        ans = 0;
    put(ans);
    return 0;
}
原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8540256.html