关于单调栈

来源:互联网 发布:sql五表关联 编辑:程序博客网 时间:2024/05/22 10:25

例题为poj2559,是一道经典例题。

#include<stdio.h>#include<algorithm>#include<iostream>#define MAXN 1000001using namespace std;struct squ{    int height ;    int  x ;}stack[MAXN];int top;int main(){    int n;    int h;    long long ans,tot,tmp;    while(scanf("%d",&n) && n)    {        top = 0;//stack中的个数        ans = 0;//最终的面积, tot为此时最大的面积        for(int i=0; i<n; i++)        {            cin >> h;            tmp = 0;//宽度            while(top > 0 && stack[top-1].height >= h)            {                 tot = stack[top-1].height * (stack[top-1].x+tmp);                if( tot > ans) ans = tot;                tmp += stack[top-1].x;                top--;            }            stack[top].height = h;            stack[top].x = 1 + tmp;            top++;        }        tmp = 0;        while( top > 0 )//栈中剩余元素        {            tot = stack[top-1].height * (stack[top-1].x + tmp);            if( tot > ans) ans = tot;            tmp+=stack[top-1].x;            top--;        }       cout << ans << endl;    }    return 0;}

关于单调栈的一个应用是  求以某一值为最小值的最大区间。




poj3494是在2559的基础上的一道沿生。看了题解才知道怎么做。

#include <iostream>#include <vector>#include <cstring>#include <string>#include <stack>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 2005;int arr[maxn][maxn];int sum[maxn][maxn];int l[maxn],r[maxn];int main(){    int m,n;    while(scanf("%d%d",&m,&n) == 2)    {        for(int i=1; i<=m; i++)            for(int j=1; j<=n; j++)                scanf("%d",&arr[i][j]);        memset(sum,0,sizeof(sum));        for(int j=1; j<=n; j++)            for(int i=1; i<=m; i++)            {                if(arr[i][j] == 1)                    sum[i][j] = sum[i-1][j] + 1;                else                    sum[i][j] = 0;            }        for(int i=1; i<=m; i++)            sum[i][0] = sum[i][n+1] = -1;        int ans = 0;        for(int i=1; i<=m; i++)        {            for(int j=1; j<=n; j++)                l[j] = r[j] = j;            for(int j=1; j<=n; j++)                while(sum[i][l[j]-1] >= sum[i][j])                    l[j] = l[l[j]-1];            for(int j=n; j>=1; j--)                while(sum[i][r[j]+1] >= sum[i][j])                    r[j] = r[r[j]+1];            for(int j=1; j<=n; j++)                ans  = max(ans,sum[i][j]*(r[j]-l[j]+1));        }        printf("%d\n",ans);    }}


0 0