타뷸레이션을 이용해 최솟값을 구하는 문제.
한 번에 성공하였음.
값을 저장할 2차원 배열 를 정의하자. 이때 는 첫번째 집에서 색칠을 시작해 번째 집을 번째 색으로 칠하기까지의 최소 비용을 나타낸다.
그래프를 그려본다면, 2번째 집 이후부터 2개의 식으로 비용이 결정됨을 알 수 있다. 예를 들어 2번째 집을 초록색으로 칠한다고 치자. 첫번째 예시를 이용하겠다.
2번째 집을 초록색으로 칠할 때 들 수 있는 비용:
-> 1번째 집, 빨강색(= 26) + 2번째 집, 초록색(= 60)
-> 1번째 집, 파란색(= 83) + 2번째 집, 초록색(= 60)
위와 같이 2가지 식으로 결정된다. 두 가지 값을 전부 쓸 수 없다. 그래서 기준을 잡아야 한다.
문제에서 요구하는 것은 최소 비용이기에, 최솟값을 쓰면 된다. 위의 경우에 대해서는 1번째 집을 빨간색으로 칠할 때의 비용과 2번째 집을 초록색으로 칠하는 비용을 더한 값이 해당된다.
이제 이를 일반화하여 수식으로 나타내자. 는 번째 집을 번째 색으로 칠할 때의 비용을 나타낸다.
이제 이를 코드로 나타내면 다음과 같다.
#include <stdio.h>
int D[1001][3];
int main()
{
int N,i,j,m;
scanf("%d",&N);
for(i=0;i<N;i++) {
scanf("%d%d%d",&D[i][0],&D[i][1],&D[i][2]);
if(i) {
D[i][0]=D[i-1][1]+D[i][0]<D[i-1][2]+D[i][0]?D[i-1][1]+D[i][0]:D[i-1][2]+D[i][0];
D[i][1]=D[i-1][0]+D[i][1]<D[i-1][2]+D[i][1]?D[i-1][0]+D[i][1]:D[i-1][2]+D[i][1];
D[i][2]=D[i-1][0]+D[i][2]<D[i-1][1]+D[i][2]?D[i-1][0]+D[i][2]:D[i-1][1]+D[i][2];
}
}
m=D[--i][0];
for(j=1;j<3;j++)
if(m>D[i][j]) m=D[i][j];
printf("%d",m);
}
D를 대입하는 부분은 더 줄일 수 있었을텐데, 일단 풀었다는 것에 의의를 두려고 한다.
전체적인 흐름은 내 코드와 매우 비슷하므로 생략한다.
올리고 싶어도 숏코딩 상위권에 올라온 분들의 코드는 너무 압축되어 있어 보기가 힘들다.
처음으로 이런 유형의 동적 프로그래밍 문제를 풀어봤다. 문제가 정형화된 것 같은데, 다른 문제도 풀어보면서 감각을 익혀야겠다.