새소식

Computer Science/코딩테스트 문제 풀이

⭐⭐⭐⭐[코드트리] 정수 사각형 최장 증가 수열

  • -

문제 

 크기의 격자 정보가 주어졌을 때, 시작점을 적절하게 잡아 상하좌우로 인접한 칸으로 계속 칸에 적혀있는 정수값이 커지도록 이동한다고 했을 때 밟고 지나갈 수 있는 최대 칸의 수를 구하는 프로그램을 작성해보세요.

 

입력 형식 

 

첫 번째 줄에는 이 주어집니다.
두 번째 줄부터 개의 줄에 걸쳐 각 행에 해당하는 개의 정수 값이 공백을 사이에 두고 주어집니다.

  • 1 ≤  ≤ 500
  • 1 ≤ 주어지는 숫자 ≤ $

 

출력 형식 

가능한 경로의 숫자들 중 최솟값의 최댓값을 출력합니다.

 

입출력 예제 

예제1 

입력:

3
2 2 1
3 1 2
4 1 2

출력:

3

 

예제2

입력:

3
5 1 3
6 1 4
7 2 3

출력:

4

 

예제 설명 

 


백트래킹으로 풀거나 DP로 풀면 된다.

 

백트래킹 방법

 

import sys sys.stdin=open('input.txt', 'r') def in_range(x, y): return 0 <= x and x < n and 0 <= y and y < n # 정수값이 작은 칸부터 순서대로 보며 # 4방향에 대해 최적의 칸 수를 계산합니다. dxs = [-1, 1, 0, 0] dys = [ 0, 0, -1, 1] # (x, y)에서 출발하여 조건을 만족하며 # 도달할 수 있는 칸의 수 중 # 최대 칸의 수를 구합니다. def DFS(x, y): # 이미 계산해본적이 있다면 # 그 값을 바로 반환합니다. if dp[x][y] != -1: return dp[x][y] # 기본값은 자기자신이 됩니다. best = 1 # 현재 (x,y) 위치를 1번 세고 시작 for dx, dy in zip(dxs, dys): nx = x + dx ny = y + dy if in_range(nx, ny) and board[nx][ny] > board[x][y]: best = max(best, DFS(nx, ny) + 1) # 다음칸으로 이동하므로 +1 dp[x][y] = best return dp[x][y] if __name__=="__main__": n = int(input()) board = [list(map(int, input().split())) for _ in range(n)] dp = [[-1] * n for _ in range(n)] # 각 칸에 시작했을 떄 # 최대로 이동할 수 있는 칸의 수 중 # 최댓값을 갱신합니다. ans = 0 for i in range(n): for j in range(n): ans = max(ans, DFS(i, j)) print(ans)

 

 

DP 방법 

import sys sys.stdin=open('input.txt', 'r') dxs, dys = [-1, 1, 0, 0], [0, 0, -1, 1] def in_range(nx, ny): return 0<=nx<n and 0<=ny<n if __name__=="__main__": n = int(input()) board = [list(map(int, input().split())) for _ in range(n)] dp = [[0] * n for _ in range(n)] cells = [] ans = 0 # 각 칸에 적혀있는 정수값 기준으로 # 오름차순이 되도록 칸의 위치들을 정렬합니다. # 편하게 정렬하기 위해 # (칸에 적혀있는 값, 행 위치, 열 위치) 순으로 넣어줍니다. for i in range(n): for j in range(n): cells.append((board[i][j], i, j)) # 오름차순으로 정렬을 진행합니다. cells.sort() # 처음 DP 값들은 전부 1로 초기화해줍니다. (해당 칸에서 시작하는 경우) for i in range(n): for j in range(n): dp[i][j] = 1 # 정수값이 작은 칸부터 순서대로 보며 # 4방향에 대해 dp 값을 갱신해줍니다. for _, x, y in cells: # 인접한 4개의 칸에 대해 갱신을 진행합니다. for dx, dy in zip(dxs, dys): nx = x + dx ny = y + dy if in_range(nx, ny) and board[nx][ny] > board[x][y]: dp[nx][ny] = max(dp[nx][ny], dp[x][y] + 1) # 전체 수들 중 최댓값을 찾습니다. for i in range(n): for j in range(n): ans = max(ans, dp[i][j]) print(ans)
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.