[파이썬] 백준 17404 : RGB거리 2 (골드4)
17404번: RGB거리 2
첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나
www.acmicpc.net
문제
풀이
0. 방향성 생각
각 색깔별로 시작해서 마지막에는 자신과 다른 색으로 끝난 색의 값 2개씩 받는다.
총 6개 중 최소값을 출력.
1. 입력
import sys
input = lambda : sys.stdin.readline().rstrip()
n = int(input())
arr = []
for _ in range(n):
arr.append(list(map(int,input().split())))
2. 함수 정의
def min_cost(idx):
dp = [[0,0,0] for _ in range(n)]
dp[0] = [10**6+1]*2
dp[0].insert(idx,arr[0][idx])
for dist in range(n-1):
for color in range(3):
if color == 0 :
dp[dist+1][0] = arr[dist+1][0] + min(dp[dist][1],dp[dist][2])
elif color == 1 :
dp[dist+1][1] = arr[dist+1][1] + min(dp[dist][0],dp[dist][2])
elif color == 2 :
dp[dist+1][2] = arr[dist+1][2] + min(dp[dist][1],dp[dist][0])
cost = dp[-1]
cost.pop(idx)
return cost
임의의 색깔에서 출발해서 출발 색깔이 아닌 다른 색에서 끝나는 값 2개씩 얻는다.
제일 중요한 점은 DP 시작 색깔이 마지막 색깔과 달라야한다.
R을 골랐으면 시작점의 G B는 다음 거리에서 절대 선택될 수 없게 10**6+1로 초기화시켜준다.
DP 시작값을 모두 R 값으로 채우면 안되냐? -> 다음 배열에 영향을 줄 수 있음.
다음 DP R값 = 다음 arr R값 + 이전 G/B 중 최소값. 이런식으로 DP 배열을 채워준다.
3. 출력
answer = []
for i in range(3):
answer.extend(min_cost(i))
print(min(answer))
답에는 R->G,B / G->R,B / B->R,G 총 6개의 결과가 들어있게 된다.
answer에 후보 6개를 넣어주고 그 중 최소값 출력한다.
전체코드
import sys
input = lambda : sys.stdin.readline().rstrip()
n = int(input())
arr = []
for _ in range(n):
arr.append(list(map(int,input().split())))
def min_cost(idx):
dp = [[0,0,0] for _ in range(n)]
dp[0] = [10**6+1]*2
dp[0].insert(idx,arr[0][idx])
for dist in range(n-1):
for color in range(3):
if color == 0 :
dp[dist+1][0] = arr[dist+1][0] + min(dp[dist][1],dp[dist][2])
elif color == 1 :
dp[dist+1][1] = arr[dist+1][1] + min(dp[dist][0],dp[dist][2])
elif color == 2 :
dp[dist+1][2] = arr[dist+1][2] + min(dp[dist][1],dp[dist][0])
cost = dp[-1]
cost.pop(idx)
return cost
answer = []
for i in range(3):
answer.extend(min_cost(i))
print(min(answer))
import sys
input = lambda : sys.stdin.readline().rstrip()
n = int(input())
arr = [list(map(int,input().split())) for _ in range(n)]
inf = 1e9
def find_cost(rgb):
dp = [[0]*3 for _ in range(n)]
dp[0] = [1e9]*3
dp[0][rgb] = arr[0][rgb]
for stage in range(n-1):
for nc in range(3):
dp[stage+1][nc] = min(dp[stage][c] for c in range(3) if c != nc) + arr[stage+1][nc]
return min(dp[-1][c] for c in range(3) if c != rgb)
print(min(find_cost(ans) for ans in range(3)))
다시 풀어본 풀이
다시 보니까 배열을 크게 만들어주는게 아니면, dp를 여러번 반복해서 풀 수 있다.
초기 state가 x개로 정해지면 x번 반복해서 도출된 output 중 결과를 선택하는 방식
'Algorithm > Dynamic Programming' 카테고리의 다른 글
[파이썬] 백준 2670 : 연속부분최대곱 (실버4) (0) | 2023.07.30 |
---|---|
[파이썬] 백준 11057 : 오르막 수 (실버1) (0) | 2023.07.30 |
[파이썬] 백준 2156 : 포도주 시식 (실버1) (0) | 2023.07.24 |
[파이썬] 백준 1149 : RGB거리 (실버1) (0) | 2023.07.20 |
[파이썬] 백준 1562: 계단 수 (골드1) (0) | 2023.07.18 |
[파이썬] 프로그래머스 : 땅따먹기 (Lv.2) (0) | 2023.07.08 |
[파이썬] 백준 11726, 11727 : 2xn 타일링, 2xn타일링 2 (실버3) (0) | 2023.06.01 |
댓글