How We Coding

[1149] RGB 거리

BOJ/DP2018. 1. 30. 21:52

http://boj.kr/1149


기본 DP2


- d[n][k] : n번째 집을 컬러 k로 칠했을 때, 1~n번째 집을 칠하는데 드는 최소비용.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
 
int rgb[1001][3];
int d[1001][3];
 
int min(int a, int b)
{
    return a > b ? b : a;
}
 
int go(int n, int k)
{
    int ans;
 
    if(n == 0return rgb[0][k];
    if(d[n][k]) return d[n][k];
 
    if(k == 0) {
        ans = go(n-11);
        ans = min(ans, go(n-12));
    }
    else if(k == 1) {
        ans = go(n-10);
        ans = min(ans, go(n-12));
    }   
    else {
        ans = go(n-10);
        ans = min(ans, go(n-11));
    }
    return d[n][k] = ans + rgb[n][k];
}
 
int main()
{
    int i, j, n;
    int ans;
    scanf("%d"&n);
    
    for(i=0; i<n; i++)
        for(j=0; j<3; j++)
            scanf("%d"&rgb[i][j]);;
 
    ans = go(n-10);
    ans = min(ans, go(n-11));
    ans = min(ans, go(n-12));
    printf("%d\n", ans);
 
    return 0;
}
cs



>> 실은 6개월전에 해결했던 문제다.

     하지만 과거에 코드를 보니, 한동안 ps를 안해서 그런지 더 멍청해진것 같다는 생각이 든다...


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
 
int rgb[1001][3], d[1001][3];
 
int min(int a, int b)
{
    return a > b ? b : a;
}
 
int go(int n, int color)
{
    int ret;
    if(n < 0return 0
    if(d[n][color]) return d[n][color];    
    ret = go(n-1, (color+1)%3);
    ret = min(ret, go(n-1, (color+2)%3));    
    return d[n][color] = ret+rgb[n][color];
}
 
int main()
{
    int i, j, n, ans;
    scanf("%d"&n);
 
    for(i=0; i<n; i++
        for(j=0; j<3; j++
            scanf("%d"&rgb[i][j]);
    
    ans = go(n-12);
    ans = min(ans, go(n-11)); 
    ans = min(ans, go(n-10)); 
    printf("%d\n", ans);
    return 0;
}
cs


- 백준해설 


i번째 집의 이웃은 i-1번째 집과 i+1번째 집. (연속)

처음집과 마지막 집은 이웃이 아니다..!!


다이나믹에서 중요한 조건중에 하나인 "연속"이라는 조건이 포함된 문제..!!

앞의 집과의 색만 다르게 칠하면 된다.



- 아래 코드는 바텀업.


1
2
3
4
5
6
7
for(int i=1; i<=n; i++) {
    d[i][0= min(d[i-1][1], d[i-1][2]) + a[i][0];
    d[i][1= min(d[i-1][0], d[i-1][2]) + a[i][0];
    d[i][2= min(d[i-1][0], d[i-1][1]) + a[i][0];
}
 
cout << min({d[n][0], d[n][1], d[n][2]}) << '\n';
cs

>> 0번째는 비워두고 하는것이 좋다. 

>> min({a, b, c}); // a, b, c 중 최소값. 

>> c++11 문법으로 아래가 함수의 원형인 것 같다. 즉 리스트로 들어가서 그 리스트들 중 최소값이 

     리턴되는 방식인 것 같다.


template<class T>
T min( std::initializer_list<T> ilist)
{
    return *std::min_element(ilist.begin(), ilist.end());
}


'BOJ > DP' 카테고리의 다른 글

[2302] 극장 좌석  (0) 2018.02.05
[1937] 욕심쟁이 판다  (0) 2018.02.01
[1309] 동물원  (0) 2018.02.01
[1932] 숫자삼각형  (0) 2018.02.01
[1463] 1로 만들기  (0) 2018.01.26