[Silver I] NM과 K (1) - 18290
성능 요약
메모리: 31120 KB, 시간: 2996 ms
분류
백트래킹, 브루트포스 알고리즘
제출 일자
2024년 11월 5일 14:53:46
문제 설명
크기가 N×M인 격자판의 각 칸에 정수가 하나씩 들어있다. 이 격자판에서 칸 K개를 선택할 것이고, 선택한 칸에 들어있는 수를 모두 더한 값의 최댓값을 구하려고 한다. 단, 선택한 두 칸이 인접하면 안된다. r행 c열에 있는 칸을 (r, c)라고 했을 때, (r-1, c), (r+1, c), (r, c-1), (r, c+1)에 있는 칸이 인접한 칸이다.
입력
첫째 줄에 N, M, K가 주어진다. 둘째 줄부터 N개의 줄에 격자판에 들어있는 수가 주어진다.
출력
선택한 칸에 들어있는 수를 모두 더한 값의 최댓값을 출력한다.
풀이
import sys N , M , K = map(int , sys.stdin.readline().split()) ans = -10000000000 mat = [[i for i in map(int , sys.stdin.readline().split())] for w in range(N)] global visited visited = [ [False]*M for _ in range(N)] # (r-1, c), (r+1, c), (r, c-1), (r, c+1) # def check_visitied(): # for i in range(len(visited)): # print(visited[i]) # print("----------------------") def check(px, py, index, sum): # print(sum) if index == K : global ans # check_visitied() ans = max(sum , ans) return dx = [1,-1,0,0] dy = [0,0,1,-1] # py if x == px else 0, 이게 왜 필요하지? # px == x라는 것은 내가 재귀함수를 실행하는 행이 이전에 실행했던 재귀함수의 행과 중복되는지 확인한다. # 따라서 지금 재귀를 돌리는 행이 이전 재귀의 행과 같은 부분은 0부터가 아닌 py부터 진행해도 무방하다. # (이전 재귀에서 탐색했기 때문) for x in range(px, N): for y in range(py if x == px else 0, M): if(visited[x][y]): continue flag = True for i in range(4): mx = x+dx[i] my = y+dy[i] # 해당되는 범위가 밖에 있는 경우. if(0 > mx or N <= mx or 0 > my or M <= my): continue if(visited[mx][my]): flag = False break if(flag): visited[x][y] = True check(x, y, index+1, sum+mat[x][y]) visited[x][y] = False check(0,0,0,0) print(ans)
재귀함수는 어릴 때 풀었던 전개도 문재 같다는 생각이든다. 삼차원으로 이루어지는 작업을 코드로써 이차원으로 옮긴 것 같아 복잡하게 느껴진다.