标签:dp
题意就是求最大子矩阵。
白书上的例题。
如果暴力枚举 左上角,然后长和宽。时间复杂度为O(m^3*n^3)。
可以定义up[][] 为某个格子最大高度,
定义 left[][]为某个格子左扫描最大。
定义 right[][]为右扫描的最大。
最后乘起来。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<stack> //#include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-8 #define LL long long #define PI 3.141592654 #define CLR(a,b) memset(a,b,of(a)) #define FOR(i,a,b) for(int i=a;i<b;i++) #define acfun std::ios::sync_with_stdio(false) #define SIZE 1000+10 using namespace std; bool g[SIZE][SIZE]; int up[SIZE][SIZE]; int left[SIZE][SIZE]; int right[SIZE][SIZE]; int main() { int n,m; int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); FOR(i,0,n) FOR(j,0,m) { char ch; scanf("%c",&ch); while(ch!='R'&&ch!='F') scanf("%c",&ch); if(ch=='R')g[i][j]=1; else g[i][j]=0; } int ans=0; FOR(i,0,n) { int lo=-1,ro=m; FOR(j,0,m) { if(g[i][j]) up[i][j]=left[i][j]=0,lo=j; else { if(i==0) { up[i][j]=1; left[i][j]=lo+1; } else { up[i][j]=up[i-1][j]+1; left[i][j]=max(left[i-1][j],lo+1); } } } for(int j=m-1;j>=0;j--) { if(g[i][j]) right[i][j]=m,ro=j; else { if(i==0) right[i][j]=ro-1; else right[i][j]=min(right[i-1][j],ro-1); ans=max(ans,up[i][j]*(right[i][j]-left[i][j]+1)); } } } printf("%d\n",ans*3); } }
标签:dp
原文地址:http://blog.csdn.net/dongshimou/article/details/42847199