https://www.acmicpc.net/problem/10844
방법 1: Top-down
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
|
import java.io.*;
public class Main {
public static int[][] numbers;
public static long mod = 1000000000;
public static int num;
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
num = Integer.parseInt(br.readLine());
numbers = new int[num + 1][10];
System.out.println(calculate(num));
} catch (Exception e) {
e.printStackTrace();
}
}
public static long calculate(int i) {
long result = 0;
if (i == 1) {
for (int j = 1; j <= 9; j++) {
numbers[i][j] = 1;
result += numbers[i][j];
}
return result;
}
calculate(i - 1);
for (int j = 1; j <= 9; j++) {
if (j <= 8) {
numbers[i][j] += numbers[i - 1][j + 1];
}
if (j == 1) {
numbers[i][j] += numbers[i - 1][9];
} else {
numbers[i][j] += numbers[i - 1][j - 1];
}
numbers[i][j] %= mod;
}
if (i == num) {
for (int j = 1; j <= 9; j++) {
result += numbers[i][j] % mod;
}
}
return result % mod;
}
}
Colored by Color Scripter
|
방법 2: Bottom-up
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
|
import java.io.*;
public class Main {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine());
int mod = 1000000000;
int[][] numbers = new int[num + 1][10];
for (int i = 1; i <= 9; i++) {
numbers[1][i] = 1;
}
for (int i = 2; i <= num; i++) {
for (int j = 0; j <= 9; j++) {
if (j == 0) {
numbers[i][j] = numbers[i - 1][j + 1];
} else if (j == 9) {
numbers[i][j] = numbers[i - 1][j - 1];
} else {
numbers[i][j] = (numbers[i - 1][j - 1] + numbers[i - 1][j + 1]) % mod ;
}
}
}
long result = 0;
for (int i = 0; i <= 9; i++) {
result = (result + numbers[num][i]) % mod;
}
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Colored by Color Scripter
|
c++소스
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
|
#include <iostream>
using namespace std;
const int DIV = 1000000000;
const int MAX = 100;
int sum[MAX + 1][10];
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
// 점화식 : D[N][i] = D[N - 1][i - 1] + D[N - 1][i + 1]
for (int i = 1; i < 10; i++)
{
sum[1][i] = 1;
}
for (int i = 2; i <= n; i++)
{
for (int j = 0; j < 10; j++)
{
if (j < 9)
{
sum[i][j] += sum[i - 1][j + 1];
}
if (j > 0)
{
sum[i][j] += sum[i - 1][j - 1];
}
sum[i][j] %= DIV;
}
}
// sum[n][i]을 더하는 과정에서 오버플로가 발생할 수 있기 때문에
// long long 자료형으로 선언
long long answer = 0;
for (int i = 0; i < 10; i++)
{
answer += sum[n][i];
}
cout << answer % DIV;
return 0;
}
Colored by Color Scripter
|
탑다운과 바텀업의 속도차이가 없었다
TIP1
인접한 모든 자리수의 차이가 1이 난다. 이런 수를 계단 수라고 한다.
먼저 작은 수들을 가지고 표현해보자.
길이가 3인 계단수의 맨 끝자리가 4가 되려면,
뒤에서 두번째 자리의 수가 3 또는 5가 되어야 한다.
즉, 길이가 2인 계단수의 맨 끝자리가 3 또는 5 이어야 한다.
다시 표현하면
길이가 3인 계단수의 끝자리가 4인 경우의 수
= 길이가 2인 계단수의 끝자리가 3인 경우의 수
+ 길이가 2인 계단수의 끝자리가 5인 경우의 수
이제 일반적인 점화식을 써보자.
길이가 N인 계단수의 끝자리가 k인 경우의 수를 D[N][k] 라고 하면,
D[N][k] = D[N - 1][k - 1] + D[N - 1][k + 1]
TIP2
예외는 대부분 경계에서 발생한다!
끝자리가 0일때, 9일때의 경우를 처리해주자
TIP3
마지막 합산하면서 오버플로가 발생할 수 있기 때문에,
answer는 큰 자료형으로 선언해주자
ex) java : long, c++ : long long 등
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ]11053번: 가장 긴 증가하는 부분 수열(java, c++) (0) | 2019.10.17 |
---|---|
[BOJ]2193번: 이친수(java, c++) (0) | 2019.10.17 |
[BOJ]15990번: 1, 2, 3 더하기 5(java, c++) (0) | 2019.10.15 |
[BOJ]16194번: 카드 구매하기 2(java, c++) (0) | 2019.10.15 |
[BOJ]11052번: 카드 구매하기(java, c++) (0) | 2019.10.14 |
댓글