백준
DP #10844: 쉬운 계단 수 [JAVA]
chaechaepower
2023. 5. 29. 00:04
https://www.acmicpc.net/problem/10844
10844번: 쉬운 계단 수
첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
www.acmicpc.net
문제 접근
계단수이기 때문에 기본적으로 둘째 자리 숫자는 첫째 자리 숫자의 -1 또는 +1한 수가 나타난다.
다만, 예외가 있는데 첫째 자리 숫자가 9인 경우는 둘째 자리에 8만 올 수 있고
N=3이상이고 첫째 자리 숫자가 1인 경우, 둘째 자리 숫자는 0이 올 수 있는데 그럼 셋째 자리 숫자는 반드시 1이 와야한다.
이러한 예외를 염두하여 관계식을 작성하면 다음과 같다.
코드
top down - 재귀
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static Long[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
int N=Integer.parseInt(bf.readLine());
dp=new Long[101][10];
for(int i=1;i<=9;i++) {
dp[1][i]=1L;
dp[2][i]=2L;
}
dp[2][9]=1L;
long sum=0;
for(int i=1;i<=9;i++) {
sum+=recur(N,i);
}
System.out.println(sum%1000000000);
bf.close();
}
static long recur(int N, int i) {
if(dp[N][i]==null) {
if(i==1) {
dp[N][1]=recur(N-2,1)+recur(N-1,2);
}
else if(i==9) {
dp[N][9]=recur(N-1,8);
}
else {
dp[N][i]=recur(N-1,i-1)+recur(N-1,i+1);
}
}
return dp[N][i]%1000000000;
}
}
bottom up - 반복문
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static Long[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
int N=Integer.parseInt(bf.readLine());
dp=new Long[101][10];
for(int i=1;i<=9;i++) {
dp[1][i]=1L;
dp[2][i]=2L;
}
dp[2][9]=1L;
for(int j=3;j<=N;j++) {
for(int i=1;i<=9;i++) {
if(i==1) {
dp[j][1]=(dp[j-2][1]+dp[j-1][2])%1000000000;
}
else if(i==9) {
dp[j][9]=dp[j-1][8]%1000000000;
}
else {
dp[j][i]=(dp[j-1][i-1]+dp[j-1][i+1])%1000000000;
}
}
}
long sum=0;
for(int i=1;i<=9;i++) {
sum+=dp[N][i];
}
System.out.println(sum%1000000000);
bf.close();
}
}
▲ 참고 및 주의사항
1. N이 최대 100까지 가능하므로 즉, 100자리 수가 올 수 있으므로 long 타입을 써야한다.
2. 모듈러 연산 관련
(A+B) %C = (A%C + B%C)%C
(A*B)%C = (A%C * B%C)%C
3. 좀 더 깔끔한 풀이
https://st-lab.tistory.com/134