본문 바로가기
Algorithm/BOJ

[BOJ]11726번: 2×n 타일링(java, c++)

by HBGB 2019. 10. 14.

https://www.acmicpc.net/problem/11726

 

11726번: 2×n 타일링

2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오. 아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.

www.acmicpc.net

 

방법 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
import java.io.*;
 
public class Main {
 
    public static int[] arrCount;
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
            int num = Integer.parseInt(br.readLine());
            arrCount = new int[num + 1];
            
            System.out.println(calculate(num));
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static int calculate(int num) {
 
        if (num <= 2) {
            return num;
        }
 
        if (arrCount[num] > 0) {
            return arrCount[num];
        }
        
        arrCount[num] = calculate(num-1+ calculate(num-2);
        
        return arrCount[num] % 10007;
    }
}
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
#include <iostream>
 
using namespace std;
 
const int DIV = 10007;
const int MAX = 1000;
int D[MAX + 1];
 
// 점화식 : D[n] = D[n - 1] + D[n - 2]
int make_tile(int n)
{
    if (D[n] > 0)
    {
        return D[n];
    }
    // 종료조건
    if (n <= 1)
    {
        return D[n] = 1;
    }
 
    return D[n] = (make_tile(n - 1+ make_tile(n - 2)) % DIV;
}
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    int n;
    cin >> n;
 
    make_tile(n);
 
    cout << D[n];
 
    return 0;
}
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
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[] arrCount = new int[1001]; // int[] arrCount = new int[n + 1] 에서 수정..런타임 에러..
            
            arrCount[1= 1;
            arrCount[2= 2;
            
            for (int i = 3; i < arrCount.length; i++) {
                arrCount[i] = (arrCount[i - 1+ arrCount[i - 2])  % 10007;
            }
            
            System.out.println(arrCount[num]);
            
        } 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
#include <iostream>
 
using namespace std;
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    int n;
    cin >> n;
 
    const int DIV = 10007;
    const int MAX = 1000;
    int D[MAX + 1];
 
    D[0= 1;
    D[1= 1;
    
    // 점화식 : D[n] = D[n - 1] + D[n - 2]
    for (int i = 2; i <= n; i++)
    {
        D[i] = (D[i - 1+ D[i - 2]) % DIV;
    }
 
    cout << D[n];
 
    return 0;
}
Colored by Color Scripter

 

 

이 문제는 탑다운 방식이 바텀업 방식보다 빨랐다. 

 

TIP1

2 * n 크기의 직사각형을 1 * 2, 2 * 1 타일로 채우는 방법이므로 

사각형을 놓는 방법은 2가지임을 알 수 있다. 

  • 가로 길이가 1 늘어나는 방법
  • 가로 길이가 2 늘어나는 방법

 

각 방법이 가로길이  ? 에서부터 증가시키는 것인지 파악하면 된다.

2 * n 를 채우는 방법의 수를 D(n) 이라 하면,

D(n) = D(n - 1) x 가로길이가 1 늘어나는 방법의 수

          + D(n - 2) x 가로길이가 2 늘어나는 방법의 수

 

이후는 피보나치 수열처럼 계산하면 된다. 

 

 

TIP2

1
int[] arrCount = new int[num + 1]; //( X )

배열을 선언할 때 입력받은 변수로 배열 길이를 대입하지 말자

 
1
2
3
4
int[] arrCount = new int[1001];  //( O )
            
arrCount[1= 1;
arrCount[2= 2;

초기 값 2개를 입력해 주어야 하므로,

만약 입력받은 수가 2보다 작다면 런타임 에러가 발생하게 된다. 

 

댓글