https://www.acmicpc.net/problem/1149

문제
RGB거리에는 집이 N개 있다. 거리는 선분으로 나타낼 수 있고, 1번 집부터 N번 집이 순서대로 있다.
집은 빨강, 초록, 파랑 중 하나의 색으로 칠해야 한다. 각각의 집을 빨강, 초록, 파랑으로 칠하는 비용이 주어졌을 때, 아래 규칙을 만족하면서 모든 집을 칠하는 비용의 최솟값을 구해보자.
- 1번 집의 색은 2번 집의 색과 같지 않아야 한다.
- N번 집의 색은 N-1번 집의 색과 같지 않아야 한다.
- i(2 ≤ i ≤ N-1)번 집의 색은 i-1번, i+1번 집의 색과 같지 않아야 한다.
입력
첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나 같은 자연수이다.
출력
첫째 줄에 모든 집을 칠하는 비용의 최솟값을 출력한다.
풀이
https://haerxeong.tistory.com/19
[BOJ] 9465번: 스티커
https://www.acmicpc.net/problem/9465 문제상근이의 여동생 상냥이는 문방구에서 스티커 2n개를 구매했다. 스티커는 그림 (a)와 같이 2행 n열로 배치되어 있다. 상냥이는 스티커를 이용해 책상을 꾸미려고
haerxeong.tistory.com
어떻게 풀지 한참을 고민하던 중, 예전에 푼 '스티커'라는 문제를 통해 해답을 얻었다.
처음에는 dp라는 일차원 리스트에 최소 합을 저장해야겠다는 생각으로, 어떻게 해야 각 단계별 최솟값을 한 리스트에 넣을 수 있을까 고민했다.
그러나 위 문제의 풀이를 통해, 모든 경우에 대한 최솟값을 저장한 후, 최종적인 최솟값을 출력하면 되는구나!라는 해답을 얻을 수 있었다.
N = int(input())
li = [list(map(int, input().split())) for _ in range(N)]
for i in range(1, N):
li[i][0] += min(li[i - 1][1], li[i - 1][2])
li[i][1] += min(li[i - 1][0], li[i - 1][2])
li[i][2] += min(li[i - 1][0], li[i - 1][1])
print(min(li[N - 1]))

입력값이 이처럼 n행 3열로 주어진다는 점을 생각해보면,
- 2행의 1열까지의 최소합에 포함될 수 있는 1행의 값은 2열 또는 3열
- 2행의 2열까지의 최소합에 포함될 수 있는 1행의 값은 1열 또는 3열
- 2행의 3열까지의 최소합에 포함될 수 있는 1행의 값은 1열 또는 2열
이러한 방법으로 3열에 대한 모든 최소의 합을 구했다고 생각하면 된다.
그후 마지막 열에 대한 최솟값을 출력함으로써 답을 구한 것이다.
역시 DP는 쉽지 않다.🥹
DP를 풀 때는 '해당 값에 포함될 수 있는 전 단계의 값이 어느것인지!'를 파악하도록 노력해야겠다.
'Coding Test > Problems' 카테고리의 다른 글
| [BOJ | Python] 11568번: 민균이의 계략 (0) | 2024.10.07 |
|---|---|
| [BOJ | Java] 2525번: 오븐 시계 (0) | 2024.10.01 |
| [BOJ | Python] 46733번: 셀프 넘버 (3) | 2024.09.30 |
| [BOJ | Python] 7568번: 덩치 (2) | 2024.09.30 |
| [BOJ | Python] 15656번: N과 M (7) (1) | 2024.09.29 |