코테/백준

[백준/JAVA] 2342번: Dance Dance Revolution

imname1am 2023. 5. 16. 21:29
반응형

🔺 문제

 

2342번: Dance Dance Revolution

입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자들은 각각의 방향을 나타낸다. 그리고 0은 수열의 마

www.acmicpc.net

 

 

🔺 코드

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import java.util.*;
import java.io.*;
 
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        
        // dp[N][L][R] : N개 수열을 수행했고, 왼쪽이 L. 오른쪽이 R에 있을 때 최소 누적 힘
        int dp[][][] = new int[100001][5][5];
        
        // 한 발 이동 시 드는 힘 미리 저장
        int mp[][] = {  {02222},
                        {21343},
                        {23134},
                        {24313},
                        {23431}
                     };
                     
        int n = 0, s = 1;
        for(int i = 0 ; i < 5 ; i++) {
            for(int j = 0 ; j < 5 ; j++) {
                for(int k = 0 ; k < 100001 ; k++) {
                    dp[k][i][j] = 100001 * 4;   // 충분히 큰 수로 초기화
                }
            }
        }
        dp[0][0][0= 0;    // 처음에는 아무 힘이 들지 않은 상태로 시작
        
        st = new StringTokenizer(br.readLine()," ");
        while(true) {
            n = Integer.parseInt(st.nextToken());
            
            if(n == 0)
                break;
            for(int i = 0 ; i < 5 ; i++) {
                if( n == i ) {  // 두 발이 같은 자리에 있을 수 없음
                    continue;
                }
                // 오른발을 옮겨 현재 모습이 됐을 때 최소 힘 저장
                for(int j = 0 ; j < 5 ; j++) {
                    dp[s][i][n] = Math.min(dp[s - 1][i][j] + mp[j][n], dp[s][i][n]);
                }
            }
            
            for(int j = 0 ; j < 5 ; j++) {
                if( n == j ) {  // 두 발이 같은 자리에 있을 수 없음
                    continue;
                }
                // 왼발을 옮겨 현재 모습이 됐을 때 최소 힘 저장
                for(int i = 0 ; i < 5 ; i++) {
                    dp[s][n][j] = Math.min(dp[s - 1][i][j] + mp[i][n], dp[s][n][j]);
                }
            }
            s++;
        }
        s--;
        
        int min = Integer.MAX_VALUE;
        for(int i = 0 ; i < 5 ; i++) {
            for(int j = 0 ; j < 5 ; j++) {
                min = Math.min(min, dp[s][i][j]);   // 모두 수행했을 때 최소값 찾기
            }
        }
        System.out.println(min);    // 최솟값 출력
    }
}
cs
✅ 해결 아이디어
✔ 3차원 DP 테이블
- dp[N][L][R] : 
N개 수열을 수행했고, 왼쪽이 L. 오른쪽이 R에 있을 때 최소 누적 힘

 

알고리즘과 해설은... 아래 다른 풀이들이 더 잘 적어두셔서 링크 첨부로 대체...

 


🔺 다른 풀이들

- 과정 설명 최고! (복습용)

 

[백준] 2342 - Dance Dance Revolution

https://www.acmicpc.net/problem/2342 2342번: Dance Dance Revolution 입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자

blog.everdu.ga

 

 

 

[백준] 알고리즘 분류(다이나믹 프로그래밍,JAVA)2342번, Dance Dance Revolution

문제 링크 2342번: Dance Dance Revolution 입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자들은 각각의 방향

tussle.tistory.com

 

백준 2342번 Dance Dance Revolution

https://www.acmicpc.net/problem/2342 2342번: Dance Dance Revolution 입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자

marbin-spectrum.tistory.com

 

 

 

- 분할 정복으로 푸심

 

[BOJ 백준] Dance Dance Revolution (2342) Java

링크 : https://www.acmicpc.net/problem/2342 문제 설명 : 더보기 승환이는 요즘 "Dance Dance Revolution"이라는 게임에 빠져 살고 있다. 하지만 그의 춤 솜씨를 보면 알 수 있듯이, 그는 DDR을 잘 하지 못한다. 그

subbak2.com

 

 

- Bottom-Up Top-Down 방식 모두 활용하심

 

[ BOJ ][JAVA][2342] Dance Dance Revolution

www.acmicpc.net/problem/2342 2342번: Dance Dance Revolution 입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자들은 각

coder-in-war.tistory.com


💬 느낀 점

3차원 DP 배열 이용하는 거는 ... 이제 익숙해져야하나 싶당,,,,ㅠ

 

 

1회독 2회독 3회독 4회독 5회독
V 7/7      

 

 

(+7/7 2회독)

 

[ BOJ ][JAVA][2342] Dance Dance Revolution

www.acmicpc.net/problem/2342 2342번: Dance Dance Revolution 입력은 지시 사항으로 이루어진다. 각각의 지시 사항은 하나의 수열로 이루어진다. 각각의 수열은 1, 2, 3, 4의 숫자들로 이루어지고, 이 숫자들은 각

coder-in-war.tistory.com

해당 블로그 코드를 보고 제출했다... (Bottom-Up 방식)

개인적으로 첫 번째로 올려둔 코드보다 얘가 더 이해하기 좋았다.

근데 아직 혼자 풀라면 못 풀겠어서 77번 더 복습해야할듯,,,,😳

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.util.*;
import java.io.*;
 
public class Main {
    static int INF = 987654321;
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        List<Integer> list = new ArrayList<>();
        list.add(0);
        
        while(true) {
            int num = Integer.parseInt(st.nextToken());
            if(num == 0)    break;
            list.add(num);        
        }
        
        int len = list.size();
        int[][][] dp = new int[len][5][5];
        for(int k = 0 ; k < len ; k++) {
            for(int i = 0 ; i < 5 ; i++) {
                for(int j = 0 ; j < 5 ; j++) {
                    dp[k][i][j] = INF;
                }
            }
        }
        dp[0][0][0= 0;
        
        for(int idx = 0 ; idx < len - 1 ; idx++) {
            int next = list.get(idx + 1);
            
            for(int i = 0 ; i < 5 ; i++) {
                for(int j = 0 ; j < 5 ; j++) {
                    int now = dp[idx][i][j];
                    
                    if(next != j) {
                        dp[idx + 1][next][j] = Math.min(dp[idx + 1][next][j], now + solve(i, next));
                    }
                    if(next != i) {
                        dp[idx + 1][i][next] = Math.min(dp[idx + 1][i][next], now + solve(j, next));
                    }
                }
            }
        }
        
        int ans = Integer.MAX_VALUE;
        for(int i = 0 ; i < 5 ; i++) {
            for(int j = 0 ; j < 5 ; j++) {
                ans = Math.min(ans, dp[len - 1][i][j]);
            }
        }
        
        System.out.println(ans);
    }
    
    private static int solve(int l, int r) {
        if(l == r)      return 1;               // 같은 지점 : 1
        else if(l == 0return 2;               // 중심 -> 다른 : 2
        else if(Math.abs(l - r) == 2return 4;   // 반대편 : 4
        else return 3;                          // 다른 -> 인접 : 3
    }
}
 
cs


(참고)

✔ Do it 알고리즘 코딩테스트 자바편

 

반응형