이 문제에서는 0/1과 같은 온라인 이진수를 포함하는 크기 n*m의 2차원 행렬 bin[][]이 제공됩니다. 우리의 임무는 모두 1이고 최대 면적을 반환하는 최대 크기의 직사각형 이진 부분행렬을 찾는 프로그램을 만드는 것입니다.
문제를 이해하기 위해 예를 들어보겠습니다.
입력
bin[][] = { {1, 0, 1, 1, 1} {0, 1, 1, 1, 1} {0, 0, 1, 1, 1} {1, 1, 1, 1, 1} }
출력
12
설명
이 직사각형의 경우 최대 면적입니다.
1, 1, 1 1, 1, 1 1, 1, 1 1, 1, 1
솔루션 접근 방식
문제를 해결하려면 1로만 구성된 가능한 가장 큰 직사각형 부분행렬을 찾아야 합니다. 그리고 이를 위해서는 현재 행이 직사각형으로 만들어질 때까지의 최대 면적을 찾아야 합니다.
현재 행까지의 영역은 열의 현재 요소까지 연속된 수를 먼저 구하여 계산됩니다. 그리고 우리는 한 번 같거나 더 큰 수를 가진 요소를 고려할 것입니다. 즉, 모든 숫자가 다른 경우 가장 작은 것으로 간주합니다. 지금까지 가장 큰 영역을 가진 행이 결과가 됩니다.
예시
우리 솔루션의 작동을 설명하는 프로그램
#include <bits/stdc++.h> using namespace std; #define R 4 #define C 5 int calcAreaTillRow(int row[]){ stack<int> area1s; int tos; int maxArea = 0; int curArea = 0; int i = 0; while (i < C) { if (area1s.empty() || row[area1s.top()] <= row[i]) area1s.push(i++); else { tos = row[area1s.top()]; area1s.pop(); curArea = tos * i; if (!area1s.empty()) curArea = tos * (i − area1s.top() − 1); maxArea = max(curArea, maxArea); } } while (!area1s.empty()) { tos = row[area1s.top()]; area1s.pop(); curArea = tos * i; if (!area1s.empty()) curArea = tos * (i − area1s.top() − 1); maxArea = max(curArea, maxArea); } return maxArea; } int calcmaxRecSubMat1(int bin[][C]){ int result = calcAreaTillRow(bin[0]); for (int i = 1; i < R; i++) { for (int j = 0; j < C; j++) if (bin[i][j]) bin[i][j] += bin[i − 1][j]; result = max(result, calcAreaTillRow(bin[i])); } return result; } int main(){ int bin[][C] = { {1, 0, 1, 1, 1}, {0, 1, 1, 1, 1}, {0, 0, 1, 1, 1}, {1, 1, 1, 1, 1} }; cout<<"The area of maximum size rectangle binary sub−matrix with all 1s is "<<calcmaxRecSubMat1(bin); return 0; }
출력
The area of maximum size rectangle binary sub-matrix with all 1s is 12