
?最大子矩陣...懸線法..時間復雜度O(nm)
懸線法就是記錄一個H向上延伸的最大長度(懸線), L, R向左向右延伸的最大長度, 然后通過遞推來得到.?
------------------------------------------------------------------
#include<bits/stdc++.h>
using namespace std;
#define ok(c) ((c) == 'F' || (c) == 'R')
const int maxn = 1009;
int H[maxn][maxn], L[maxn][maxn], R[maxn][maxn], N, M;
bool F[maxn][maxn];
void Read() {
cin >> N >> M;
for(int i = 0; i < N; i++)
? ?for(int j = 0; j < M; j++) {
char c = getchar();
for(; !ok(c); c = getchar());
F[i][j] = c == 'F';
? ?}
}
int main() {
Read();
for(int i = 0; i < N; i++) {
L[i][0] = F[i][0];
for(int j = 1; j < M; j++)
? ?L[i][j] = F[i][j] ? L[i][j - 1] + 1 : 0;
R[i][M - 1] = F[i][M - 1];
for(int j = M - 2; ~j; j--)
? ?R[i][j] = F[i][j] ? R[i][j + 1] + 1 : 0;
}
memset(H, 0, sizeof H);
for(int i = 1; i < N; i++)
for(int j = 0; j < M; j++) if(F[i][j] && F[i - 1][j]) {
? ?H[i][j] = H[i - 1][j] + 1;
? ?L[i][j] = min(L[i][j], L[i - 1][j]);
? ?R[i][j] = min(R[i][j], R[i - 1][j]);
}
int ans = 0;
for(int i = 0; i < N; i++)
? ?for(int j = 0; j < M; j++) if(F[i][j])
? ? ? ?ans = max(ans, (H[i][j] + 1) * (L[i][j] + R[i][j] - 1));
cout << 3 * ans << "\n";
return 0;
}
------------------------------------------------------------------?
3039: 玉蟾宮
Time Limit:?2 Sec??Memory Limit:?128 MB
Submit:?581??Solved:?352
[Submit][Status][Discuss]Description
有一天,小貓rainbow和freda來到了湘西張家界的天門山玉蟾宮,玉蟾宮宮主藍兔盛情地款待了它們,并賜予它們一片土地。
這片土地被分成N*M個格子,每個格子里寫著'R'或者'F',R代表這塊土地被賜予了rainbow,F代表這塊土地被賜予了freda。
現在freda要在這里賣萌。。。它要找一塊矩形土地,要求這片土地都標著'F'并且面積最大。
但是rainbow和freda的OI水平都弱爆了,找不出這塊土地,而藍兔也想看freda賣萌(她顯然是不會編程的……),所以它們決定,如果你找到的土地面積為S,它們每人給你S兩銀子。
Input
第一行兩個整數N,M,表示矩形土地有N行M列。
接下來N行,每行M個用空格隔開的字符'F'或'R',描述了矩形土地。
Output
輸出一個整數,表示你能得到多少銀子,即(3*最大'F'矩形土地面積)的值。
Sample Input
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
Sample Output
45
HINT
對于50%的數據,1<=N,M<=200
對于100%的數據,1<=N,M<=1000
Source
?