給定 m×n 的 0/1 矩陣('F' 視為 1,'R' 視為 0),求全 1 子矩陣的最大面積,輸出面積×3。多測試案例。m,n ≤ 1000。
將二維問題轉化為一維「最大矩形面積」問題(POJ 1506 / HDU 1506):
height[j] = 該列連續 1 的高度(若當前格為 0 則歸 0)。height[1..n],求直方圖中最大矩形面積。L[j]:左側第一個高度 < height[j] 的位置。R[j]:右側第一個高度 < height[j] 的位置。R[j] - L[j] - 1,面積 = height[j] * 寬度。
int height[1005], L[1005], R[1005];
char s[10];
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
scanf("%s", s);
if (s[0] == 'F') height[j] += 1;
else height[j] = 0;
}
// 求 L[]
for (int j = 1; j <= n; ++j) {
L[j] = j;
while (L[j] > 1 && height[L[j]-1] >= height[j])
L[j] = L[L[j]-1]; // 跳躍優化
}
// 求 R[]
for (int j = n; j >= 1; --j) {
R[j] = j;
while (R[j] < n && height[R[j]+1] >= height[j])
R[j] = R[R[j]+1];
}
for (int j = 1; j <= n; ++j)
ans = max(ans, height[j] * (R[j] - L[j] + 1));
}
printf("%d\n", 3 * ans);
%s 讀取字符串,取 s[0] 判斷。height、L、R 數組大小開 n+2 避免越界。L[j] = L[L[j]-1] 是將 O(n²) 降為 O(n) 的關鍵。HDU 1505 是「最大全 1 子矩陣」的標準解法:逐行構建直方圖高度,配合單調棧 O(n) 求最大矩形。掌握此模板,可解決所有二維 0/1 矩陣最大子矩陣問題。