-
DP 실전문제알고리즘 (코딩테스트) 2024. 10. 20. 14:50
1. 프로그래머스 - N으로 표현
https://school.programmers.co.kr/learn/courses/30/lessons/42895
아이디어)
dp[i] = N을 i번 사용해서 만들 수 있는 숫자들의 집합
i번 사용했을때 가능한 숫자들은, i-1번까지 사용한 숫자들과 사칙연산을 통해 계산
ex)
- dp[1] = { 5 } : 5를 한번만 사용
- dp[2] = N을 2번 이어붙인 수+ 이전연산과의 사칙연산 조합
{ 55, 5+5, 5-5, 5/5, 5*5 } : 55, dp[1]과의 사칙연산조합
- dp[3]은 dp[1]과 dp[2]의 조합
{ 555, 55+5, 55-5, 55*5, 55/5, 10+5, 10-5, 10*5, 10/5, ..... }
- dp[4]는 dp[1]과 dp[3]의 조합
- dp[5]는 dp[1]과 dp[4]의 조합 or dp[2]와 dp[3]의 조합
이를 반복하여 dp[i]에서 number가 발견되는 순간, 최소한 횟수 반환
def solution(N, number): dp = [set() for _ in range(9)] # dp[1] ~ dp[8] 사용 # N을 여러 번 이어붙인 경우는 미리 dp에 넣어준다 # ex. dp[1] = {5}, dp[2] = {55}, dp[3] = {555} for i in range(1, 9): dp[i].add( int(str(N)*i) ) # dp[i] : i번 사용한 결과는 dp[j]와 dp[i-j]의 조합 # ex. dp[5] = dp[1]+dp[4] or dp[2]+dp[3] or dp[3]+dp[2] or dp[4]+dp[1] for i in range(1, 9): for j in range(1, i): for op1 in dp[j]: for op2 in dp[i-j]: dp[i].add(op1+op2) #덧셈 dp[i].add(op1-op2) #뺄셈 dp[i].add(op1*op2) #곱셈 if op2 != 0: dp[i].add(op1//op2) #나눗셈 if number in dp[i]: return i return -1 # 8까지 사용했는데도 못찾은 경우는 return되는게 없고, 여기서 -1을 반환한다
2. 프로그래머스 - 등굣길
https://school.programmers.co.kr/learn/courses/30/lessons/42898
# 이 문제는 행,열이 반대로 표기되어 있어 유의해야 함!!! # dp는 행열을 반대로 표기해서 평소대로 생각하자 def solution(m, n, puddles): dp = [ [0]*(m+1) for _ in range(n+1) ] dp[1][1] = 1 puddles = [[y,x] for [x,y] in puddles] # 행/열이 반대로 표기되어 있어 # 위에서 오거나, 왼쪽에서 오거나 둘 중 하나 for i in range(1,n+1): for j in range(1,m+1): if i==1 and j==1: continue if [i, j] in puddles: dp[i][j] = 0 else: dp[i][j] = ( dp[i-1][j] + dp[i][j-1] ) % 1000000007 return dp[n][m]
3. 프로그래머스 - 정수 삼각형
https://school.programmers.co.kr/learn/courses/30/lessons/43105
2차원 dp로 해결
dp를 트리 모양대로 초기화 하고, 모양대로 합을 차례로 더해감
- 트리의 양 끝 요소는 더하는데 문제없으나 가운데 끼인 요소는 더할 수 있는 경우가 2가지 존재
- 합이 더 큰 경우만 dp에 저장한다
>> 완성된 dp의 맨 마지막 배열이 삼각형 최종 누적 합이고, 이 중 가장 큰 값이 정답
def solution(triangle): N = len(triangle) dp = [[0]*len(row) for row in triangle] dp[0][0] = triangle[0][0] # 삼각형 각 층을 순차적으로 탐색 for i in range(1, N): for j in range(len(triangle[i])): if j == 0: #삼각형 맨 왼쪽 (위에서 하나만 더할 수 있음) dp[i][j] = dp[i-1][j] + triangle[i][j] elif j == len(triangle[i]) - 1: #삼각형 맨 오른쪽 (위에서 하나만 더할 수 있음) dp[i][j] = dp[i-1][j-1] + triangle[i][j] else: # 삼각형 중간 - 위에서 두 값 중 큰 값을 더함 dp[i][j] = max( dp[i-1][j-1], dp[i-1][j] ) + triangle[i][j] return max(dp[-1])
'알고리즘 (코딩테스트)' 카테고리의 다른 글
DFS/BFS (0) 2024.10.24 이분탐색 (0) 2024.10.22 완전탐색(Brute Force) (0) 2024.10.21 DP (다이나믹 프로그래밍) 기본개념/기본문제 (0) 2024.10.17 다익스트라와 MST(최소신장트리) (1) 2024.10.16