알고리즘
[DP] 백준 11726번 - 2 x n 타일링 (Java)
대추언니
2019. 4. 12. 22:58
문제
2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 10007로 나눈 나머지를 출력하는 프로그램을 작성하시오.
풀이과정
이 문제 역시 DP로 풀 수 있는 문제입니다.
n = 1 일 때는 2 x 1 타일로 채우는 한 가지 방법이 있습니다.
n = 2 일 때는 2 x 1 타일 2개로 채우거나, 1 x 2 타일 2개로 채우는 방법이 있겠지요.
그럼 n = 3 일 때는 어떨까요?
n = 2 일 때 채웠던 방법들에 2 x 1 타일을 추가할 수 있을 것입니다.
또한, n = 1 일 때 채웠던 방법들에 1 x 2 타일 2개를 정사각형 모양으로 추가할 수 있습니다.
이런식으로 (n - 1) 일 때의 가짓수와 (n - 2) 일 때의 가짓수를 더하면 n일 때의 가짓수를 쉽게 구할 수 있습니다.
이를 점화식으로 표현하면 다음과 같습니다.
DP(0) = DP(1) = 1 DP(n) = DP(n-1) + DP(n-2) |
이 때, 주의할 점이 한가지가 있습니다.
배열에 값을 저장할 때, 10007를 나눈 나머지를 저장하지 않으면 오버플로우가 발생하여 잘못된 값이 들어가게 됩니다.
(이걸로 한참 헤맸습니다ㅠㅠ)
그래서 반드시 배열의 각 원소에 값을 저장할 때, 10007로 나눈 나머지를 저장해야 합니다. (밑의 코드에서 16번째 줄을 참고해주세요)
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(br.readLine());
int[] cases = new int[num + 1];
cases[0] = 1;
cases[1] = 1;
for (int i = 2; i < num + 1; i++) {
cases[i] = (cases[i - 1] + cases[i - 2] % 10007);
}
System.out.println(cases[num]);
}
}
|
cs |