单调栈

来源:互联网 发布:雅思口语全薇机经 知乎 编辑:程序博客网 时间:2024/04/25 16:27

单调栈: 顾名思义就是在入栈时遵循单调原则,可以求出一个元素向左(或向右)所能扩展到的最大长度,并不是说在这一段区间内是单调的,而是保证在该区间内该元素一定是最大或最小;




poj2796点击打开链接

大意:给一数组,求使得某段区间所有数之和乘上该区间中的最小值的值最大,找到这个最小值。

#include<algorithm>#include<cstring>#include<stack>#include<iostream>#include<cstdio>using namespace std;const int maxn = 100005;long long l[maxn], r[maxn], a[maxn], sum[maxn];int main(void){    int n;    while(cin >> n)    {        memset(sum, 0, sizeof(sum));        for(int i = 1; i <= n; i++)        {            scanf("%lld", &a[i]);            sum[i] = sum[i-1] + a[i];        }        stack<int> s;        while(!s.empty()) s.pop();        for(int i = 1; i <= n; i++)        {            while(s.size() && a[s.top()] >= a[i]) s.pop();            l[i] = s.size() == 0 ? 1 : (s.top()+1);            s.push(i);        }        while(!s.empty()) s.pop();        for(int i = n; i > 0; i--)        {            while(s.size() && a[s.top()] >= a[i]) s.pop();            r[i] = s.size() == 0 ? n : (s.top()-1);            s.push(i);        }        long long ans = 0;        int x = 1, y = 1, z;        for(int i = 1; i <= n; i++)        {            //cout << sum[i] << endl;            long long temp = 0;            temp = a[i] * (sum[r[i]] - sum[l[i]-1]);            if(ans < temp)            {                ans = temp;                x = l[i];                y = r[i];                z = i;            }        }        printf("%lld\n%d %d\n", ans, x, y);    }    return 0;}


poj3250点击打开链接

题意:每头牛向右看,只能看到比它矮的(相等的看不到),问你所有牛能看到的牛总数;

#include<iostream>#include<stack>#include<cstdio>using namespace std;const int maxn = 80005;int a[maxn], r[maxn];int main(void){    int n;    while(cin >> n)    {        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);        stack<int> s;        while(!s.empty()) s.pop();        for(int i = n; i >= 1; i--)        {            while(s.size() && a[s.top()] < a[i]) s.pop();            r[i] = s.size() == 0 ? n : (s.top()-1);            s.push(i);        }        long long sum = 0;        for(int i = 1; i <= n; i++)            sum += r[i] - i;            //cout << r[i] - i << ' ';        printf("%lld\n", sum);    }    return 0;}


0 0
原创粉丝点击