传送门
1531 山峰
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题目描述 Description
Rocky山脉有n个山峰,一字排开,从西向东依次编号为1, 2, 3, ……, n。每个山峰的高度都是不一样的。编号为i的山峰高度为hi。
小修从西往东登山。每到一座山峰,她就回头观望自己走过的艰辛历程。在第i座山峰,她记录下自己回头能看到的山峰数si。
何谓“能看到”?如果在第i座山峰,存在j<k<i,hj<hk,那么第j座山峰就是不可见的。除了不可见的山峰,其余的山峰都是可见的。
回家之后,小修把所有的si加起来得到S作为她此次旅行快乐值。现在n座山峰的高度都提供给你了,你能计算出小修的快乐值吗?
输入描述 Input Description
第一行一个整数n(n<=15000)。
第i+1(1<=i<=n)行是一个整数hi(hi<=109)。
输出描述 Output Description
仅一行:快乐值。
样例输入 Sample Input
5
2
1
3
5
9
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
说明:s1=0, s2=1, s3=2, s4=1, s5=1。
【思路】
维护单调栈...递减....
我的不是正解....我自己YY的啊。
【code】
#include<iostream> #include<cstdio> using namespace std; int n,x,top,ans; int stack[15009]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); if(!top||stack[top]>=x){ ans+=top; stack[++top]=x; } if(stack[top]<x){ ans+=top; while(stack[top]<x&&top) top--; stack[++top]=x; } } printf("%d ",ans); return 0; }
发现无论新加入元素比栈顶元素大还是小都要加上站内元素的个数...
所以我写的是正解....开心....WAW///
-------------------分割线-------------------------------------
//20180717
用栈来模拟,每加入一座山峰的高度,栈中高度小于它的就被清走,(被清走的就是看不见的山峰)
所以在栈中,左边的元素一定比右边的元素大,所以相当于维护了一个单调递减的栈。
每来到一座山峰看栈中有多少个元素,就是在这个山峰看到的山峰的个数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #define N 15020 using namespace std; int n,top,ans; int sta[N]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int h; scanf("%d",&h);ans+=top; while(top&&sta[top]<h)top--; sta[++top]=h; } cout<<ans<<endl; return 0; }