G - Bad Hair Day (单调栈)

                                        G - Bad Hair Day 

题目描述

Farmer John的奶牛在风中凌乱了它们的发型……
每只奶牛都有一个身高hi(1 ≤ hi ≤ 1,000,000,000),现在在这里有一排全部面向右方的奶牛,一共有N只(1 ≤ N ≤ 80,000)。对于奶牛i来说,如果奶牛i+1,i+2,……,N这些奶牛的身高严格小于奶牛i,则奶牛i可以看到它们凌乱的发型。
比如下面这个例子:

* * * * = *
= * * * = *
= * - * = * 奶牛面向这边-->
= * = * = *
= - = = = *
= = = = = =
1 2 3 4 5 6
('*'表示空的,这是译者为了格式特意弄的,原题没有)

令ci表示第i只奶牛能够看到的发型数量,请计算c1 + c2 + c3 + … + cN的值
对于上面这个例子,答案为3 + 0 + 1 + 0 + 1 + 0=5。

输入

第一行:奶牛数量N
第二到N+1行:第i+1行输入奶牛i的身高

输出

第一行:一个整数即c1到cN的和

样例输入

6
10
3
7
4
12
2

样例输出

5

 

 

 

首先我们先模拟一下:

身高:             10     3     7    4    12    2

牛(下标):  1       2    3     4    5      6

就以牛1为例子进行模拟:

  1. 首先,第一头牛要看他前面的牛,那就让牛1 入栈
  2. 牛1要先和牛2比身高,如果牛2比他低, 则牛1可看到牛2,牛1仍然在栈顶,然后sum(牛1) += 1;
  3. 牛1再看牛3, 发现又能看到  ,再加1;
  4. 牛1继续看,能看到牛4, 再加1;
  5. 牛1再看牛5时,发现看不到,则牛1出栈,牛5入栈,改牛5看他前面的牛
  6. .......................................

  从此过程不难看出,该题和单调栈息息相关,一直在维护栈顶元素

ac代码:

/*该题利用了单调栈的性质,一直维护栈顶元素
,栈顶元素每次看到的数字之和即为栈顶元素可以看到的所有数目*/
#include
#include
#include

using namespace std;

const int maxn = 8*1e4+5;
long long a[maxn];

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
	
	stackS;
	S.push(a[0]);
	long long sum = 0;
	for(int i = 1; i < n; i++){
		while(S.size() > 0&&S.top() <= a[i]) S.pop();
		sum += S.size();
		S.push(a[i]);
	} 
	
	printf("%lld\n", sum);
	return 0;
}

 

你可能感兴趣的:(单调栈)