728x90

문제

 

 

접근 방식

문제 자체는 간단한데 어떻게 풀어야 할지 어려웠던 문제였지만

일단 규칙을 찾아야 할 거 같아서 수들을 적다 보니 특징을 발견해서 풀 수 있었다.

1	10	101
2	12	121 123
3	21	210 212
4	23	232 234
5	32	
6	34
7	43
8	45
9	54	(생략)
	56
	65
	67
	76
	78	787 789
	87	876 878
	89	898
	98	987 989

 

각각 한 자리부터 세 자리까지의 쉬운 계단 수를 나열한 목록인데

0과 9로 끝나는 부분만 제외한 모든 수들이 2배씩 늘어나고

0과 9로 끝나는 경우만 그대로 하나인 것을 알 수 있다.

 

0으로 끝나는 경우에는 09가 될 수 없으니 01만 올 수 있고

9로 끝나는 경우도 마찬가지로 90이 될 수 없으니 98만 올 수 있다.

 

0과 9를 제외한 1~8로 끝나는 수들은 전부 자기 자신 - 1, 자기 자신 + 1

이렇게 두 가지로 늘어날 수 있기 때문에 이 특징들을 이용해 계산해 주면 된다.

 

우선 DP 테이블은 각 자릿수별로 특정 숫자로 끝나는 가짓수를 기록하기 위해

다음과 같이 2차원 배열로 정의했다.

dp[n][10] = 1 ~ n번째 자리수의 0 ~ 9로 끝나는 경우의 수

 

이제 위에서 정리한 쉬운 계단 수의 특징들을 가지고 테이블을 채워주면 되는데

0과 9의 경우는 기존 가짓수를 그대로 따라가기 때문에

d[i][0] = d[i-1][1]
d[i][9] = d[i-1][8]

 

위와 같이 이전 값을 그대로 기록해주면 된다.

 

각각 이전 자리수의 0번과 9번 값을 가져오지 않고 1번과 8번을 가져오는 이유는

이전 자리수가 1인 경우에만 10처럼 0으로 끝날 수 있고

이전 자리수가 8인 경우에만 89처럼 9로 끝날 수 있기 때문이다.

d[i][j] = d[i-1][j-1] + d[i-1][j+1]

 

2 ~ 8의 경우에는 이전 자릿수의 j-1과 j+1인 경우에 j가 될 수 있으니

두 값을 모두 더해주면 된다.

 

풀이

public class Main {

	private static final int MOD = 1_000_000_000;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		byte n = Byte.parseByte(br.readLine());

		long[][] dp = new long[n + 1][10];

		dp[1] = new long[]{0, 1, 1, 1, 1, 1, 1, 1, 1, 1};

		for (byte i = 2; i <= n; i++) {
			dp[i][0] = dp[i - 1][1] % MOD;
			dp[i][9] = dp[i - 1][8] % MOD;
			for (byte j = 1; j < 9; j++) {
				dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1]) % MOD;
			}
		}

		long count = 0;

		for (byte i = 0; i < 10; i++) {
			count += dp[n][i];
		}

		System.out.println(count % MOD);
	}
}

 

'Java > Algorithms' 카테고리의 다른 글

[백준] 2217번 : 로프  (1) 2023.12.26
[백준] 1931번 : 회의실 배정  (0) 2023.12.25
[백준] 15486번 : 퇴사 2  (1) 2023.12.24
[백준] 14501번 : 퇴사  (1) 2023.12.24
[백준] 9461번 : 파도반 수열  (1) 2023.12.23

+ Recent posts