题意:给出一个矩阵,'F'表示空地,'R'表示障碍物,问不包含障碍物的最大子矩阵的面积是多少,输出面积×3。
题解:dp题,从上到下扫描,用up[i][j]、left[i][j]、right[i][j]分别表示在矩阵第i行第j列的位置,它的上界是第几行,左右边界又是第几列,这样S[i][j] = up[i][j] * (right[i][j] - left[i][j] + 1),那么状态转移方程up[i][j] = up[i - 1][j] + 1,left[i][j] = max(left[i - 1][j],pl + 1),right[i][j] = max(right[i - 1][j],pr - 1),pl和pr代表最靠近当前位置的障碍物的位置。
#include <stdio.h>
#include <algorithm>
using namespace std;
const int N = 1005;
char g[N][N], ch;
int r, c, up[N][N], left[N][N], right[N][N];
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &r, &c);
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
ch = getchar();
while (ch != 'F' && ch != 'R')
ch = getchar();
g[i][j] = ch;
}
int res = 0;
for (int i = 0; i < r; i++) {
int pl = -1, pr = c;
for (int j = 0; j < c; j++) {
if (g[i][j] == 'R') {
up[i][j] = left[i][j] = 0;
pl = j;
}
else {
up[i][j] = i == 0 ? 1 : up[i - 1][j] + 1;
left[i][j] = i == 0 ? pl + 1 : max(left[i - 1][j], pl + 1);
}
}
for (int j = c - 1; j >= 0; j--) {
if (g[i][j] == 'R') {
right[i][j] = c;
pr = j;
}
else {
right[i][j] = i == 0 ? pr - 1 : min(right[i - 1][j], pr - 1);
res = max(res, up[i][j] * (right[i][j] - left[i][j] + 1));
}
}
}
printf("%d\n", res * 3);
}
return 0;
}