#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <string>
#include <math.h>
#include <iomanip>
#include <map>
#include <stack>
#include <list>
#include <set>
#include <iterator>
using namespace std;
typedef unsigned short int us;
typedef short int s;
typedef unsigned long int ul;
typedef long int l;
typedef unsigned long long int ull;
typedef long long int ll;
typedef string str;
typedef char c;
typedef bool b;
typedef double d;
typedef long double ld;
typedef float f;
const l INF = 1000000001;
const ll L_INF = 1000000000000000001;
const double EPS = 10e-9;
#define FOR(x, y, z) for(ll z = x; z < y; ++z)
#define FORE(x, y, z) for(ll z = x; z <= y; ++z)
#define FORD(x, y, z) for(ll z = x; z > y; --z)
#define FORDE(x, y, z) for(ll z = x; z >= y; --z)
#define REP(x, y) for(ll y = 0; y < x; ++y)
#define PF push_front
#define POF pop_front
#define PB push_back
#define POB pop_back
#define MP make_pair
l** grid;
l maxRectangle(l row, l n);
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
l n, result = 0;
cin >> n;
grid = new l * [n];
REP(n, i)
grid[i] = new l[n];
REP(n, i)
{
REP(n, j)
{
cin >> grid[i][j];
grid[i][j] = !grid[i][j];
}
}
result = max(result, maxRectangle(0, n));
FOR(1, n, i)
{
FOR(0, n, j)
{
if (grid[i][j])
grid[i][j] += grid[i - 1][j];
}
result = max(result, maxRectangle(i, n));
}
cout << result << "\n";
cin.ignore();
cin.get();
}
l maxRectangle(l row, l n)
{
stack<l> result;
l max_area = 0, area = 0, top_val;
l k = 0;
while (k < n)
{
if (result.empty() || grid[row][k] >= grid[row][result.top()])
result.push(k++);
else
{
top_val = grid[row][result.top()];
result.pop();
area = top_val * k;
if(!result.empty())
area = top_val * (k - result.top() - 1);
max_area = max(area, max_area);
}
}
while (!result.empty())
{
top_val = grid[row][result.top()];
result.pop();
area = top_val * k;
if (!result.empty())
area = top_val * (k - result.top() - 1);
max_area = max(area, max_area);
}
return max_area;
}
Tu jest mój kod, który kiedyś napisałem do tego zadania. Powinien być troche bardziej zrozumiały od tego z książeczki.
Ogólnie pomysł był taki, żeby dla każdego wiersza, traktować każde G[i] jako wysokość szukanego prostokąta. Wtedy trzeba tylko znaleźć ile bezpośrednio na lewo i na prawo jest takich G[j], że G[j] >= G[i] i z tego mamy pole prostokąta. Można to zrobić stosem monotonicznym, który gwarantuje że kolejne G[i] są niemalejące.