티스토리 뷰
백준 1562 : 계단 수
등급 : Gold I
1562번: 계단 수
첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
사용 알고리즘 : Bitmasking, Dynamic Programming
사용 자료구조 : -
다이나믹 프로그래밍에 비트필드 배열을 추가한 형식의 문제이다.

길이가 5인 수의 경우를 예로 들어보자.
행 부분은 길이, 열 부분은 그 위치에 올 수 있는 숫자이다.

계단 수는 0으로 시작할 수 없으므로 위와 같은 상태가 된다.

두 자리 수의 경우, 0은 1에서만 올 수 있으므로 1.
→ 두 자리 수이며, 두 번째 자리가 0인 계단 수는 10 하나 뿐이다.
→ 마찬가지로 9의 경우도 8에서만 올 수 있다.
중간에 있는 경우, 2를 예로 들면 1과 3에서 올 수 있으므로 1 + 1 = 2.

이와 같은 과정을 거쳐 완성하면 위와 같은 DP 테이블이 완성된다.
여기까지 이해가 되었다면, 이제 어떤 숫자가 등장하였는지 비트필드 차원을 추가시켜주면 된다.

0부터 9까지 모든 숫자가 포함되었는지를 확인할 것이므로 총 2¹⁰개의 비트필드가 필요하다.
위의 예인 45656은 4, 5, 6이 표시된 것이기 때문에 비트로 표현하면 0001110000₂이며, 112가 된다.
이러한 비트 패턴을 위의 DP테이블에 추가할 것이다.

첫 번째 자리의 경우 하나씩만 들어가므로, 수에 맞춰 비트를 Shift해 준 값만큼 필드에 마스킹이 된다.
이후 자리의 경우는 이전 자리에 현재 자리의 수를 OR연산한 것에 이전 자리의 비트를 더해 갯수를 구할 수 있다.
→ 예를 들어 길이가 5인 수이며, 현재 자리에 6이 나오는 경우라고 하고, 4, 5, 6이 마킹된 경우를 보도록 하자.
나올 수 있는 수는 45656, 45456, 65456이 있겠다. 이때 4565에서 1개, 4545에서 1개, 6545에서 1개가 올 수 있다.
이때, DP[5][6][0b000111000]에서 2개(4, 5, 6 마킹), DP[5][6][0b000011000]에서 1개(4, 5 마킹)가 올 수 있다.
즉 (이전 비트 | 현재 숫자 비트)값을 이전 비트들의 합으로 나타낼 수 있다.
1. 3차원 DP 배열을 생성해준다.
( 첫 번째는 길이, 두 번째는 올 수 있는 숫자 (0~9), 세 번째는 올 수 있는 숫자를 마킹할 마스킹 비트 )
2. 첫 번째 자리의 경우 0에는 올 수 없고, 1~9만 올 수 있으므로 1~9와, 해당하는 비트를 마스킹한 곳에 1을 표시.
→ DP[1][i][1<<i] = 1;
3. 이후 자리는 위에서 설명한 것과 같이 0과 9의 경우 양 옆에서 하나씩, 나머지는 양쪽에서 받아오는 것으로 구현.
그리고 비트를 확인하여 이전 비트에 현재 수를 OR 연산한 값의 갯수를 더해준다.
4. 이후 최대 길이에서 모든 비트가 체크되어 있는 경우를 구한다.
( 문제 조건에 따라, 각 과정에서 모두 %연산을 취해준다. )
'알고리즘 > 코딩테스트' 카테고리의 다른 글
[백준] 2104번 : 부분배열 고르기 - C++ / JAVA (0) | 2023.01.04 |
---|---|
[백준] 11003번 : 최솟값 찾기 - C++ / JAVA (1) | 2022.12.28 |
[백준] 12865번 : 평범한 배낭 - C++ / JAVA (0) | 2022.12.23 |
[백준] 1083번 : 소트 - C++ / JAVA (0) | 2022.12.22 |
[백준] 16946번 : 벽 부수고 이동하기 4 - C++ / JAVA (0) | 2022.12.22 |