单调栈 Largest Submatrix of All 1’s poj3494

单调栈的运用

求最大的全为1的子矩阵,可转化为,对于每一行,转化为直方表的形式然后利用单调栈求解

比如:

对于矩阵

0 0 1 1 //第一行对应的直方图就是0,0,2,2

1 1 1 1//同理为1 1 1 1

然后对于每个直方图求最大矩阵

参照http://www.cnblogs.com/felixfang/p/3676193.html 解法

/*
ID: meixiny1
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
#define PI 3.1415926535898
//#define LOCAL
int mp[2005][2005];
int sum[2005][2005];
int ans[2005][2005][2];
int st[2005];
int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//    freopen("out.txt","w",stdout);
#endif
    int n,m;
    while(scanf("%d%d",&m,&n)!=EOF){
        MEM(sum,0),MEM(mp,0),MEM(ans,0);
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++)
                scanf("%d",&mp[i][j]);
        }
        for(int i=1;i<=n;i++)sum[m][i]=mp[m][i];
        for(int i=m-1;i>=1;i--){
            for(int j=1;j<=n;j++){
                if(mp[i][j])sum[i][j]=sum[i+1][j]+1;
            }
        }
        for(int i=1;i<=m;i++){
            int top = 0;
            for(int j=1;j<=n;j++){
                while(top>0 && sum[i][j]<=sum[i][st[top-1]])top--;
                ans[i][j][0] = top==0?1:st[top-1]+1;
                st[top++]=j;
            }
            top = 0;
            for(int j=n;j>=1;j--){
                while(top>0 && sum[i][j]<=sum[i][st[top-1]])top--;
                ans[i][j][1] = top==0?n:st[top-1]-1;
                st[top++]=j;
            }
        }
        int tot = 0;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                tot = max(tot, (j-ans[i][j][0]+ans[i][j][1]-j+1)*sum[i][j]);
            }
        }
        printf("%d\n",tot);
    }
    return 0;
}









你可能感兴趣的:(栈,单调栈)