POJ3494-Largest Submatrix of All 1’s
作者:互联网
这是一道比较灵活的单调栈的题目,尽管我在做之前就知道它是单调栈,但还是想了很长一会儿才想到写法。
写单调栈最重要的一点就是弄清要依据什么东西单调。本题看似是求矩形面积,而且矩形与矩形之间还会分隔开,看起来貌似跟单调栈扯不上任何关系。但应该想到:若某一行的某一列出现了一个0,那么在这一列的前面行中不论出现了多少个1,都跟后续的计算无关了,所以可以把这一列已经出现过的数全视为0;出现了1的,就看它之前连续地出现过几个1,这一列的面积就是这一列出现过的1的数量了。
问题就转化成了对于每一列求类似单调栈经典题中的最大矩形了,总的复杂度为。常数非常大,有超时的风险,我TLE了一发,然后马上想到了一个剪枝:对于每一行单调栈的过程中,将0入栈其实没有实际的意义,因此在入栈时判断一下0是否需要入栈即可。加了这个剪枝就过了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
int n, m;
pair<int, int> p[2005];
int main()
{
while (~scanf("%d%d", &n, &m))
{
int i, j, res = 0;
for (i = 0; i <= m; i++)
p[i].first = p[i].second = 0;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= m; j++)
{
scanf("%d", &p[j].first);
if (p[j].first)
p[j].second++;
else
p[j].second = 0;
}
stack<pair<int, int> > sta;
for (j = 1; j <= m; j++)
{
if (sta.empty() || p[j].second >= sta.top().second)
{
if (p[j].first)
sta.push(p[j]);
continue;
}
pair<int, int> t(0, 0);
while (!sta.empty())
{
if (sta.top().second < p[j].second)
break;
t.first += sta.top().first;
t.second = sta.top().second;
sta.pop();
res = max(res, t.first * t.second);
}
if (p[j].first)
{
t.first += p[j].first;
t.second = p[j].second;
sta.push(t);
}
}
pair<int, int> t(0, 0);
while (!sta.empty())
{
t.first += sta.top().first;
t.second = sta.top().second;
sta.pop();
res = max(res, t.first * t.second);
}
}
printf("%d\n", res);
}
return 0;
}
标签:POJ3494,sta,res,top,Submatrix,second,Largest,include,first 来源: https://www.cnblogs.com/zetaaaaaaaa/p/15847265.html