这题的话,求最大01矩阵,我们找每行的某一点,先初始化这点的高,再向两边延伸L[i],R[i],遍历所有节点就可以求出所有的面积
L[i]的求法可以用dp,一开始只看懂了用底*高的求法,一直在想dp在哪里...很好的题呀
状态转移方程
L[i] = L[L[i]-1] (a[k][i]<=a[k][L[i]-1])
先求出每行某一点的高度,剩下的问题和1506一模一样了
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <stack> #include <queue> using namespace std; const int inf = (1<<31)-1; const int MAXN = 1e3+10; int dp[MAXN][MAXN]; int L[MAXN]; int R[MAXN]; int main() { int t,n,m; char s[3]; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%s",s); if(s[0]=='F')dp[i][j] = dp[i-1][j] + 1; else dp[i][j] = 0; } } int ans,mmax = -inf; for(int i=1;i<=n;i++){ dp[i][0] = dp[i][m+1] = -1; for(int j=1;j<=m;j++){ L[j] = j; while(dp[i][j]<=dp[i][L[j]-1]) L[j] = L[L[j]-1]; //dp优化 } for(int j=m;j>=1;j--){ R[j] = j; while(dp[i][j]<=dp[i][R[j]+1]) R[j] = R[R[j]+1]; } for(int j=1;j<=m;j++){ ans = 3*dp[i][j]*(R[j]-L[j]+1); mmax = max(ans,mmax); } } cout<<mmax<<endl; } //cout << "Hello world!" << endl; return 0; }