bzoj3039 玉蟾宫

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3039

【题解】

最大全1子矩阵。

用单调栈,先处理出来(i,j)向左有多少个连续的1,然后根据这个加入单调栈。

记得加的时候pos需要更新到最后弹出的位置。

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 1000 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

char tmp[23];
int n, m, ans;
int mp[M][M], a[M][M];

struct pa {
    int pos, d;
    pa() {}
    pa(int pos, int d) : pos(pos), d(d) {}
}st[M];
int stn=0;
inline void doit(int pos, int d) {
    int ps = pos;
    while(st[stn].d > d) {
        ans = max(ans, (pos-st[stn].pos)*st[stn].d);
        ps = min(ps, st[stn].pos);
        --stn;
    }
    st[++stn] = pa(ps, d);
}

int main() {
    cin >> n >> m;
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j) {
            scanf("%s", tmp);
            if(tmp[0] == 'F') mp[i][j] = 1;
            else mp[i][j] = 0;
        }
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=m; ++j)
            if(mp[i][j] == 0) a[i][j] = 0;
            else a[i][j] = a[i][j-1] + 1;
    for (int i=1; i<=m; ++i) {
        stn = 0;
        for (int j=1; j<=n; ++j) 
            doit(j, a[j][i]);
        doit(n+1, 0);
    }
    cout << ans*3;
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/galaxies/p/bzoj3039.html