출처 : https://www.acmicpc.net/problem/17404
풀이 방법
dp에서 문제를 dp[i][j]를 i번째에 j색을 선택했을 때 최소 비용으로 설정했다. ( 0<= j <= 2 0 == R, 1 == G, 2 ==B)
이렇게 설정 후 for 문을 1부터 N-1까지 돌며 각 경우에 대해 각 경우에 대해
dp[i][0]일 땐 dp[i-1][1], dp[i-1][2] 중 작은 값을 선택
dp[i][1]일 땐 dp[i-1][0], dp[i-1][2] 중 작은 값을 선택
dp[i][2]일 땐 dp[i-1][1], dp[i-1][0] 중 작은 값을 선택 후 자신의 돈 더하기
위 과정을 해주면 된다.
여기서 추가적으로 고려해야할 점은 처음과 끝이 다르게 선택되어야 한다는 점이다.
이를 위해 첫 선택을 강제하는 방법을 선택했다.
for 0~2까지 돌며 현재 선택된 색이 아닌 경우의 dp[0]값을 987654321처럼 큰 값을 할당하여 선택되지 않도록 했다.
또 마지막에서 시작 색과 다른 dp[N-1][j] j색을 선택해서 답을 구했다.
N = int(input())
money = [] ## 가격을 저장할 이차원 배열
for i in range(N):
a, b, c = map(int, input().split())
money.append([a, b, c])
ans = 987654321
for i in range(3): ## start를 선택했다. 선택을 강제하자
dp = [[0, 0, 0] for _ in range(N)] ## dp[i][j] i번째에 j를 선택했을 때 최소 비용
for j in range(3): ## i가 아닌 건 처음에 선택되지 않도록 큰 값으로 설정
if i != j:
dp[0][j] = 987654321
dp[0][i] = money[0][i] ## 0번째 i를 선택한 경우 돈을 설정
for j in range(1, N): ## 3번 돌리기
dp[j][0] = min(dp[j-1][1], dp[j-1][2]) + money[j][0]
dp[j][1] = min(dp[j-1][0], dp[j-1][2]) + money[j][1]
dp[j][2] = min(dp[j-1][0], dp[j-1][1]) + money[j][2]
for j in range(3):
if i != j:
ans = min(ans, dp[N-1][j])
print(ans)
'Algorithm' 카테고리의 다른 글
[백준] 주사위 굴리기 14499번 (python) 구현 (0) | 2024.09.03 |
---|---|
[백준] 내려가기 2096번 (python) 원도우를 활용한 DP (0) | 2024.08.31 |
[백준] 암호 코드 2011번 (python) DP (0) | 2024.08.18 |
[백준] ACM Craft 1005번 (python) 위상정렬 + dp (0) | 2024.08.04 |
[백준] 치킨 배달 15686번 (python) 조합 (0) | 2024.08.04 |