본문으로 바로가기

[BOJ 1915] 가장 큰 정사각형 (Python)

category 카테고리 없음 2021. 5. 16. 22:37

https://www.acmicpc.net/problem/1915

 

1915번: 가장 큰 정사각형

첫째 줄에 n, m(1 ≤ n, m ≤ 1,000)이 주어진다. 다음 n개의 줄에는 m개의 숫자로 배열이 주어진다.

www.acmicpc.net

완전탐색으로 풀면 시간초과가 날 수 있는 문제.

DP를 이용하면 O(NM)으로 풀 수 있다.

핵심 점화식은

d[i][j] = min(d[i - 1][j - 1], d[i - 1][j], d[i][j - 1]) + 1

여기서 d[i][j]는 i행 j열을 오른쪽 끝으로 하는 정사각형 한변의 최대 길이이다.

최종적으로 d 배열에서 최댓값을 구하면 만들 수 있는 가장 큰 정사각형의 변의 길이가 나오고

제곱하여 답을 구할 수 있다.

import sys

input = sys.stdin.readline
n, m = map(int, input().split())
arr = [list(map(int, input().rstrip())) for _ in range(n)]
d = [[0] * m for _ in range(n)]
for i in range(n):
    for j in range(m):
        if arr[i][j] == 1:
            if i >= 1 and j >= 1:
                d[i][j] = min(d[i - 1][j - 1], d[i - 1][j], d[i][j - 1]) + 1
            else:
                d[i][j] = 1

print(max(list(map(max, d))) ** 2)

DP는 아이디어를 생각해내는 것이 핵심인데,

경험에 의해 이 아이디어를 캐치하는 능력을 기를 수 있다고 생각한다. 

풀다보면 감각이 생길 것이다.

 

완전탐색으로 풀 수 있는 문제는

시간 초과가 우려될 경우 DP를 의심해봐야한다.

또한, 앞서 구한 부분문제의 답이 다른 문제의 답으로 이용되는 경우여야 한다.

 

점화식을 찾아낸다면 굉장히 간단하게 풀 수 있다.