Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 앱 비교 프로젝트
- StateObject
- ObservedObject
- 데이터베이스 공부
- iOS 개발 오류
- 숭실대
- Apple Developer Academy @ POSTECH
- 네이버 치지직
- Swift 디자인패턴
- ObservableObject
- global soop
- 운영체제
- 제앱소
- 애플 디벨로퍼 아카데미 21주차 회고
- Swift 문법
- 애플 아카데미 후기
- SWIFT
- OS
- 치지직
- sqoop
- 애플 디벨로퍼 아카데미
- apple developer academy 후기
- 데이터베이스
- useReducer
- 네이버 부스트캠프
- react
- 애플 디벨로퍼 아카데미 후기
- swift문법
- 소프트웨어분석및설계
- Swift 기능
Archives
- Today
- Total
사과하는 제라스
[백준 BOJ 10844번] 쉬운 계단 수 본문
목차
728x90
반응형
출처 : https://www.acmicpc.net/problem/10844
1. 문제
45656이란 수를 보자.
이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.
N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자. 0으로 시작하는 수는 계단수가 아니다.
2. 입력
첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 100보다 작거나 같은 자연수이다.
1
2
3. 출력
첫째 줄에 정답을 1,000,000,000으로 나눈 나머지를 출력한다.
9
17
4. 풀이
이 문제는 풀이에 있어서 다음 2가지 기본적인 규칙만 코드로 잘 구현해두면 작성하기 쉽다.
1. 가장 큰자리에는 0이 올 수 없다. 2. 앞에 작성된 숫자가 9나 0이면 현재 자리수에는 8이나 1밖에 적을 수 없다.
이들을 처음 시작하는 값이 가장 큰자리수이냐(Top-Down) 작은 자리수이냐(Bottom-Up)에 따라 구현할 코드의 방식이 바뀐다.
5. 소스코드
<Top-Down 방식>
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
static Long [][] dp;
final static long MOD = 1000000000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
dp = new Long [N+1][10];
for(int i=0; i<10; i++) dp[1][i] = 1L;
//첫자리(1의자리)에는 어떤 값이 오든 1가지의 경우의 수임.
//왼쪽(큰자리수)에서 시작해서 오른쪽(작은자리수)으로 가짓수를 찾아갈 것이니 종착점의 경우의 수는 1가지이다.
long result = 0;
for(int i=1; i<10; i++){
result += caseOf(N,i);
}
System.out.println(result%MOD);
}
public static long caseOf(int digit, int val){ //caseOf는 digit자릿수에 val이 왔을 때 앞에 자리들은 채우는 경우의 수가 어떻게 됨?을 리턴하는 함수이다.
if(digit == 1) return dp[digit][val];
if(dp[digit][val] == null){
if(val == 0) dp[digit][val] = caseOf(digit-1, 1);
else if(val == 9) dp[digit][val] = caseOf(digit-1, 8);
else dp[digit][val] = caseOf(digit-1, val+1) + caseOf(digit-1, val-1);
}
return dp[digit][val]%MOD;
}
}
<Bottom-Up방식>
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
static Long [][] dp;
final static long MOD = 1000000000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
dp = new Long [N+1][10];
long result = 0;
for(int i=0; i<10; i++) dp[1][i] = 1L; //첫자리(1의자리)에는 어떤 값이 오든 1가지의 경우의 수임. 오른쪽에서 시작해서 왼쪽으로 가짓수를 찾아갈 것인데 맨 마지막에는 이미 1개로 정해져 있어야 재귀를 통해 다시 원 위치로 돌아올 때 경우의 수를 찾아갈 수 있음.
for(int i=2; i<=N; i++){
for(int j=0; j<10; j++){
if(j == 0) dp[i][j] = dp[i-1][1]%MOD;
else if(j == 9) dp[i][j] = dp[i-1][8]%MOD;
else dp[i][j] = (dp[i-1][j-1] + dp[i-1][j+1])%MOD;
}
}
for(int i=1; i<10; i++){
result += dp[N][i];
}
System.out.println(result%MOD);
}
}
6. 배운 것
주어진 크기(1,000,000,000)를 넘기지 않게 하기 위해 미리 final 상수를 위에 기입해두고 필요할 때마다 나눠주는 모습을 기본적인 스킬로 가져가야겠다.
또한, 이전의 DP문제에서도 다뤘었지만 위 <Top-Down방식>에서 쓰인 Long [][]처럼 박싱을 통해 입력받지 않은 것들에 대해 판별 시 null을 사용할 수 있도록 해야겠다.
728x90
반응형
'JAVA 백준 알고리즘 문제풀이 > 동적 계획법' 카테고리의 다른 글
[백준 BOJ 2565번] 전깃줄 (0) | 2021.12.10 |
---|---|
[백준 BOJ 11054번] 가장 긴 바이토닉 부분 수열 (0) | 2021.12.05 |
[백준 BOJ 11053번] 가장 긴 증가하는 부분 수열 (0) | 2021.12.05 |
[백준 BOJ 9184번] 신나는 함수 실행 (0) | 2021.12.04 |
[백준 BOJ 1003번] 피보나치 함수 (0) | 2021.12.04 |