单调栈的运用
求最大的全为1的子矩阵,可转化为,对于每一行,转化为直方表的形式然后利用单调栈求解
比如:
对于矩阵
0 0 1 1 //第一行对应的直方图就是0,0,2,2
1 1 1 1//同理为1 1 1 1
然后对于每个直方图求最大矩阵
参照http://www.cnblogs.com/felixfang/p/3676193.html 解法
/* ID: meixiny1 PROG: test LANG: C++11 */ #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <climits> #include <string> #include <vector> #include <cmath> #include <stack> #include <queue> #include <set> #include <map> #include <sstream> #include <cctype> using namespace std; typedef long long ll; typedef pair<int ,int> pii; #define MEM(a,b) memset(a,b,sizeof a) #define CLR(a) memset(a,0,sizeof a); const int inf = 0x3f3f3f3f; const int MOD = 1e9 + 7; #define PI 3.1415926535898 //#define LOCAL int mp[2005][2005]; int sum[2005][2005]; int ans[2005][2005][2]; int st[2005]; int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif int n,m; while(scanf("%d%d",&m,&n)!=EOF){ MEM(sum,0),MEM(mp,0),MEM(ans,0); for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++) scanf("%d",&mp[i][j]); } for(int i=1;i<=n;i++)sum[m][i]=mp[m][i]; for(int i=m-1;i>=1;i--){ for(int j=1;j<=n;j++){ if(mp[i][j])sum[i][j]=sum[i+1][j]+1; } } for(int i=1;i<=m;i++){ int top = 0; for(int j=1;j<=n;j++){ while(top>0 && sum[i][j]<=sum[i][st[top-1]])top--; ans[i][j][0] = top==0?1:st[top-1]+1; st[top++]=j; } top = 0; for(int j=n;j>=1;j--){ while(top>0 && sum[i][j]<=sum[i][st[top-1]])top--; ans[i][j][1] = top==0?n:st[top-1]-1; st[top++]=j; } } int tot = 0; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ tot = max(tot, (j-ans[i][j][0]+ans[i][j][1]-j+1)*sum[i][j]); } } printf("%d\n",tot); } return 0; }