BZOJ 3039 玉蟾宫
题意:求符合要求的最大子矩阵
首先,这道题单调栈可做,但我没有太明白,回头再补充。
另外,AC方法似乎不只有单调栈。
我们可以预处理出l[i][j]和r[i][j]表示(i,j)这个点在第i列向左和向右分别可以拓展到哪一个节点。
之后我们每次遍历到一个符合要求的点时,用它的上一排即L[i-1][j]和自己的l[i][j]更新出L[i][j]
即:L[i][j]=max(L[i-1][j],l[i][j]);
同理:R[i][j]=min(R[i-1][j],r[i][j]);
还有可以处理出来符合要求的深度
即:h[i][j]=h[i-1][j]+1;
最后 ans=max(h[i][j]*(R[i][j]-L[i][j]-1));
付上代码
1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <queue> 8 using namespace std; 9 #define N 1005 10 int h[N][N],L[N][N],R[N][N],l[N][N],r[N][N],a[N][N]; 11 int n,m; 12 char s[2]; 13 int main() 14 { 15 scanf("%d%d",&n,&m); 16 for(int i=1;i<=n;i++) 17 { 18 for(int j=1;j<=m;j++) 19 { 20 l[i][j]=j,r[i][j]=j; 21 scanf("%s",s); 22 if(s[0]=='F')a[i][j]=1; 23 } 24 r[i][m+1]=m+1; 25 l[i][0]=0; 26 } 27 for(int i=1;i<=n;i++) 28 { 29 for(int j=1;j<=m;j++) 30 { 31 if(a[i][j]) 32 { 33 l[i][j]=l[i][j-1]; 34 } 35 } 36 for(int j=m;j>0;j--) 37 { 38 if(a[i][j]) 39 { 40 r[i][j]=r[i][j+1]; 41 }else 42 { 43 R[i][j]=m+1; 44 } 45 } 46 } 47 int ans=0; 48 for(int i=1;i<=m;i++)L[0][i]=0,R[0][i]=m+1; 49 for(int i=1;i<=n;i++) 50 { 51 for(int j=1;j<=m;j++) 52 { 53 if(a[i][j]) 54 { 55 h[i][j]=h[i-1][j]+1; 56 L[i][j]=max(l[i][j],L[i-1][j]); 57 R[i][j]=min(r[i][j],R[i-1][j]); 58 ans=max(ans,(R[i][j]-L[i][j]-1)*h[i][j]); 59 } 60 } 61 } 62 printf("%d\n",ans*3); 63 }