模拟栈
栈的入栈、出栈、返回栈顶、返回栈的最小值的操作
【用一个数组和变量(记录栈顶位置)实现栈结构】
class Solution
{
private:
int a[100000], minn[100000];
int size =0;
public:
void push(int value)
{
a[size] = value;
if (size == 0)
minn[0] = value;
else
minn[size] = minn[size-1] < value ? minn[size-1] : value;
size++;
}
void pop()
{
size--;
}
int top()
{
if (size)
return a[size-1];
exit(1);
}
int min()
{
if (size)
return minn[size-1];
exit(1);
}
};
表达式计算
单调栈
牛客一个小栗子Largest Rectangle in a Histogram
单调栈处理问题的思想在于及时排除不可能的选项,保持策略集合的高度有效性和秩序性
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 10;
ll n;
ll a[N], st[N], w[N], ans;
int main()
{
while (scanf("%lld", &n) && n != 0)
{
memset(a, 0, sizeof(a));
ans = 0;
for (ll i = 1; i <= n; i++)
scanf("%lld", &a[i]);
ll p = 0;
a[n + 1] = 0; //最后要整个出栈,所以认为a[0]=a[n+1]=0;
for (ll i = 1; i <= n + 1; i++) //单调栈算法
{
if (a[i] >= st[p]) //单调递增栈
{
st[++p] = a[i]; //入栈
w[p] = 1;
}
else
{
ll width = 0;
while (a[i] < st[p])
{
width += w[p]; //累计宽度
ans = max(ans, width * st[p]); //更新答案
p--; //出栈
}
st[++p] = a[i]; //入栈
w[p] = width + 1; //最终的单增栈里面每个数的w[j]表示与左边比它小的第一个数之间,有w[j]-w[i]个数,既比a[i]大,又比a[j]大
}
}
printf("%lld\n", ans);
}
}