洛谷P4147 玉蟾宫(动规:最大子矩形问题/悬线法)
题目链接:传送门
题目大意:
求由F构成的最大子矩阵的面积。输出面积的三倍。
1 ≤ N,M ≤ 1000。
思路:
悬线法模板题。
#include <bits/stdc++.h> using namespace std; const int MAX_N = 1e3 + 5; int N, M; char mat[MAX_N][MAX_N]; int lef[MAX_N][MAX_N], rig[MAX_N][MAX_N], up[MAX_N][MAX_N]; void init() { for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) if (mat[i][j] == 'F') lef[i][j] = lef[i][j-1] + 1; else lef[i][j] = 0; for (int j = M; j >= 1; j--) if (mat[i][j] == 'F') rig[i][j] = rig[i][j+1] + 1; else rig[i][j] = 0; } } void dp() { int ans = 1; for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) { if (mat[i][j] == 'F') { if (i > 1 && mat[i-1][j] == 'F') { up[i][j] = up[i-1][j]+1; lef[i][j] = min(lef[i][j], lef[i-1][j]); rig[i][j] = min(rig[i][j], rig[i-1][j]); } else up[i][j] = 1; } else up[i][j] = 0; int len = rig[i][j] + lef[i][j] - 1; int high = up[i][j]; int a = min(len, high); ans = max(ans, a*a); ans = max(ans, len*high); } } cout << ans*3 << endl; } int main() { cin >> N >> M; for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) cin >> mat[i][j]; init(); dp(); return 0; }