奶牛排队(题解)
奶牛排队
【问题描述】
奶牛在熊大妈的带领下排成了一条直队。
显然,不同的奶牛身高不一定相同……
现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛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; }