传送门
写dp的时候莫名其妙写到了这题,其实就是一个单调栈的模板题.观察后可以发现最后矩阵由’a’或者’b’或者’c’组成的时候能得到的最大子矩阵是最优的.所以枚举三种情况跑一遍单调栈维护一个递增的矩形就好了.
代码
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
string org[N];
int n,m,mz[N][N],h[N][N],s[N],w[N];
int solve(){
int ans = 0;
mem(h,0);
mem(s,0);
mem(w,0);
fir(i,1,n){
int cnt = 0;
fir(j,1,m+1){
if(j != m+1 && mz[i][j] == 1) h[i][j] = h[i-1][j] + 1;
else h[i][j] = 0;
int width = 0;
while(cnt && h[i][j] <= h[i][s[cnt]]){
width += w[cnt];
ans = max(ans,h[i][s[cnt]]*width);
cnt--;
}
s[++cnt] = j;
w[cnt] = width+1;
}
}
return ans;
}
int main(){
while(cin >> n >> m){
fir(i,0,n-1)
cin >> org[i];
fir(i,0,n-1){
fir(j,0,m-1){
if(org[i][j] == 'a' || org[i][j] == 'w' || org[i][j] == 'y' || org[i][j] == 'z') mz[i+1][j+1] = 1;
else mz[i+1][j+1] = 0;
}
}
int ans = solve();
fir(i,0,n-1){
fir(j,0,m-1){
if(org[i][j] == 'b' || org[i][j] == 'w' || org[i][j] == 'x' || org[i][j] == 'z') mz[i+1][j+1] = 1;
else mz[i+1][j+1] = 0;
}
}
ans = max(ans,solve());
fir(i,0,n-1){
fir(j,0,m-1){
if(org[i][j] == 'c' || org[i][j] == 'x' || org[i][j] == 'y' || org[i][j] == 'z') mz[i+1][j+1] = 1;
else mz[i+1][j+1] = 0;
}
}
ans = max(ans,solve());
cout << ans << endl;
}
return 0;
}