単調スタックLargest Submatrix of All 1’s poj 3494


単調スタックの運用
最大のすべて1のサブマトリクスを求めて、変換することができて、各行に対して、ヒストグラムの表の形式に変換してそれから単調なスタックを利用して解きます
例:
行列の場合
0 0 1 1//1行目の対応するヒストグラムは0,0,2,2
1 1 1 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
",tot); } return 0; }