BOJ 5826 Figure Eight

BOJ 5826 Figure Eight

문제 링크:

문제 내용

n×nn \times n 크기의 사각 격자가 주어집니다. 격자의 각 칸은 . 또는 *입니다.

*인 칸들을 피해서 숫자 8을 그리려고 합니다. 이 숫자가 가져야 하는 특징은 다음과 같습니다.

  • 숫자 8은 두 개의 직사각형을 위아래로 붙인 모양입니다.
  • 두 직사각형은 모두 적어도 한 개의 칸을 내부에 포함합니다.
  • 위쪽 직사각형의 아랫변은 아래쪽 직사각형의 윗변에 완전히 포함되어야 합니다.
  • 두 직사각형의 테두리 위에 *가 한 개도 있으면 안됩니다. 직사각형의 내부에 있는 것은 상관 없습니다.

숫자 8을 그렸을 때의 점수는 두 직사각형 내부의 칸의 개수의 곱으로 정의합니다.

주어진 사각 격자에서 숫자 8을 하나 그려서 얻을 수 있는 최대 점수를 구하세요.

입력

첫 줄에는 nn이 주어집니다. (5n3005 \le n \le 300)

다음 nn줄에 걸쳐서 사각 격자가 공백 없이 주어집니다.

출력

문제의 정답을 출력합니다. 숫자 8을 그리는 방법 자체가 존재하지 않는다면 -1을 대신 출력합니다.

문제 풀이

스포일러

다음과 같은 브루트포스를 구상할 수 있습니다.

  • 두 직사각형이 공유하는 가로줄의 번호 mm을 고릅니다.
  • 가능한 왼쪽과 오른쪽 세로줄 번호의 쌍 (l,r)(l, r)에 대해, 왼쪽 변이 세로줄 ll 위에 있고 오른쪽 변이 세로줄 rr 위에 있는 위쪽 직사각형과 아래쪽 직사각형의 최대 면적을 각각 구합니다.
  • 위쪽 직사각형들에 대해서 구간 DP를 하여 [l,r][l, r]에 들어오는 모든 위쪽 직사각형 중 최대 면적을 구하고, 아래쪽 직사각형의 면적을 곱하여 아래쪽 직사각형의 가로 구간이 [l,r][l, r]일 때의 최대 점수를 구합니다.

세 번째 과정의 시간 복잡도는 O(n3)\mathcal{O}(n^3)입니다. 두 번째 과정도 이 시간 복잡도에 맞추고 싶은데, 어떤 방향으로 스위핑을 하더라도 O(n3logn)\mathcal{O}(n^3 \log n)보다 빠르게 하기 어려워 보입니다.

여기서는 비트셋을 사용할 수 있습니다. ll을 고정하고 rr을 오른쪽으로 움직이는 스위핑을 한다고 하면, 다음과 같이 할 수 있습니다.

  • 각 세로줄 ii에 대해, ii번째 세로줄에서 .인 가로줄들의 번호의 위치가 1인 비트셋 BiB_i를 전처리해 둡니다.
  • 또한, 현재 가로줄 mm에 대해, 각 세로줄 ii에서 mm번째 가로줄을 포함하는 연속한 .의 영역이 1인 비트셋 CiC_i를 만들어 둡니다.
  • 먼저 ll번째 세로줄에서, ClC_l을 가져오고, Bl+1B_{l+1}을 AND합니다.
  • rrl+2l+2부터 시작하여 mm번째 가로줄에서 *를 만나거나 줄 끝에 닿을 때까지 다음을 반복합니다.
    • BrB_{r}을 AND하여 유지합니다. 현재 비트셋은 ll부터 rr까지를 완전히 이을 수 있는 가로줄들의 집합입니다.
    • 이 집합에 CrC_{r}을 AND한 결과의 최하위 비트와 최상위 비트의 위치를 확인합니다. 최하위 비트의 위치가 mm보다 작으면, 위쪽 직사각형의 최대 면적을 얻을 수 있습니다. 마찬가지로 최상위 비트의 위치가 mm보다 크면, 아래쪽 직사각형의 최대 면적을 얻을 수 있습니다.
Last updated on