https://www.acmicpc.net/problem/14500
쉽게 말하면 테트리스에 나오는 도형들을 테트로미노라고 한다. 총 5가지의 종류가 있는데 이것들을 대칭시키거나 회전시켜도 된다.
맵을 하나 주고 그 안에 딱 하나의 테트로미노를 배치하여 그 안에 있는 숫자들의 합이 가장 큰 경우를 구해보는 문제이다.
어떤 모양으로 어디에 배치해야할지 찾는 문제이다. 딱 하나의 테트로미노만 배치해도 되기때문에 충분히 모든 경우를 찾아보아도 될 것 같다.
도형의 경우의 수도 너무 많지만, 'ㅗ' 모양의 블록을 제외하고는 상하좌우 남는 방면에 3개의 정사각형을 이어붙이다보면 만들 수 있다. 직접 그려보면 이해하기 쉬울 것이다. 나는 그 성질을 이용하여 dfs알고리즘을 적용하여 모든 도형을 만들어보고 탐색하도록 하였다.
'ㅗ'모양의 블럭은 따로 예외처리를 해주었다.
2번의 조건을 추가하였더니 시간복잡도에 걸리지 않았다.
'ㅗ'모양의 경우, 예외조건을 추가하여 cnt가 1일때 x, y에 대하여 즉, 자기자신의 dfs를 다시 호출하도록 하였다.
꽤 어려운 문제였다.
import sys
n, m = map(int, sys.stdin.readline().split())
arr = [list (map(int, sys.stdin.readline().split())) for _ in range(n)]
visited = [[0] * m for _ in range(n)]
max_val = max(map(max, arr))
res = 0
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
def is_possible(x, y):
return 0 <= x < n and 0 <= y < m and visited[x][y] == 0
def dfs(x, y, cnt, tmp):
global res
if tmp + max_val*(4-cnt) <= res:
return
if cnt == 3:
res = max(res, tmp)
return
else:
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if is_possible(nx,ny):
if cnt == 1:
visited[nx][ny] = 1
dfs(x, y, cnt + 1, tmp + arr[nx][ny])
visited[nx][ny] = 0
visited[nx][ny] = 1
dfs(nx, ny, cnt + 1, tmp + arr[nx][ny])
visited[nx][ny] = 0
for i in range(n):
for j in range(m):
visited[i][j] = 1
dfs(i, j, 0, arr[i][j])
visited[i][j] = 0
print(res)