单调栈指的是一个栈,栈内的元素是单调的。
单调递增栈:从栈底到栈顶元素依次从大到小。
单调递减栈:从栈底到栈顶元素依次从小到大。
建立一个单调栈
例:如果要维护一个递增单调栈(也就是栈顶的元素最小),那么元素要入栈时,如果为空栈或者栈顶元素比入栈元素大,就入栈,否则就依次将栈顶元素出栈,直到满足条件。
伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
| stack<int> s1;
for(遍历数组){ if(栈为空||栈顶元素大于当前元素){ 入栈; }else{ while(栈不为空&&栈顶元素小于当前元素){ 栈顶元素出栈; 更新结果; } 当前元素入栈; } }
|
应用
1.视野总和:
有n个人在排队,他们身高各不相同,都向右看,能看到比自己个子矮的人的头顶,直到下一个比自己更高的人。
输入:n个数表示n个人的身高输出:所有人能看到的头顶总和
例:输入: 4 3 7 1
输出:2
(个子为4的人能看见个子为3的人,7能看见1)
思路:本质就是找到下一个比自己个子高的人,然后计算相隔的距离(也就是中间有几个人),再加和。
可以通过构建单调递增栈来解决。当遇到下一个比自己高的人时就开始处理数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const int INT_INF = 0x3F3F3F3F; int fieldSum(vector<int>& v){ v.push_back(INT_INF); stack<int> st; int sum = 0; for(int i = 0;i<v.size();i++){ if(st.empty() || v[i]<st.top()){ st.push(v[i]); }else { while(!(st.empty() || v[i]<st.top())){ int top = st.top(); st.pop(); sum += (i - top - 1); } st.push(v[i]); } } return sum; }
|
2.柱形图中的最大矩形面积
链接:https://ac.nowcoder.com/acm/contest/22669/Q
柱状图是有一些宽度相等的矩形下端对齐以后横向排列的图形,但是小A的柱状图却不是一个规范的柱状图,它的每个矩形下端的宽度可以是不相同的一些整数,分别为a[i]a[i]a[i],每个矩形的高度是h[i]h[i]h[i],现在小A只想知道,在这个图形里面包含的最大矩形面积是多少
输入描述:
1 2 3
| 一行一个整数N,表示长方形的个数 接下来一行N个整数表示每个长方形的宽度 接下来一行N个整数表示每个长方形的高度
|
输出描述:
输入
1 2 3
| 7 1 1 1 1 1 1 1 2 1 4 5 1 3 3
|
输出
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 32 33 34 35 36 37 38 39 40 41
| #include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; typedef long long int ll; const int INF = 0x3f3f3f3f; ll maxSqu(vector<pii> vec){ vec.push_back(make_pair(-1*INF,0)); stack<pii> st; ll max = -1*INF; for(int i = 0;i<vec.size();i++){ if(st.empty() || st.top().first<= vec[i].first){ st.push(vec[i]); }else{ int wid = 0; while(!st.empty() && st.top().first > vec[i].first){ pii top = st.top(); st.pop(); wid+=top.second; ll res = ll(wid)*top.first; max = max>res?max:res; } st.push(vec[i]); st.top().second += wid; } } return max; } int main(){ int n; cin>>n; vector<pii> v(n); for(int i = 0;i<n;i++){ cin>>v[i].second; } for(int i = 0;i<n;i++){ cin>>v[i].first; } cout<<maxSqu(v); return 0; }
|