Baekjoon
11727 - 2 x n 타일링2
kjy0349
2022. 4. 19. 17:58
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 | 256 MB | 44267 | 26509 | 21036 | 59.311% |
2 x n 직사각형을 1 x 2, 2 x 1, 2 x 2 타일로 채우는 경우의 수를 구하는 문제이다.
이렇게 여러가지 방법으로 경우의 수를 구할 때는 점화식을 이용해서 푸는게 일반적이다.
각 n에대해 2 x n 크기의 직사각형을 채우는 방법의 수가 들어있는 배열을 d라고하자.
d[N]에대한 점화식을 구하기 위해 아래와 같은 과정이 필요하다.
d[N - 1]의 값을 임의로 구했다고 했을 때, d[N - 1]을 구한 후에는 한 줄이 남으므로 1 . 2 x 1 타일 1개로 한 줄을 채우는 경우 한 가지이고,
d[N - 2]의 값을 구했다고 하면 d[N - 2]를 구한 후에는 두 줄이 남으므로 1 . 2 x 1 타일 2개로 두 줄을 채우는 경우 2 . 1 x 2 타일 2개로 두 줄을 채우는 경우 총 두가지가 있다.
따라서 d[N] = d[N - 1] + d[N - 2]라는 점화식을 세울 수 있게 된다. 따라서 d[N]을 구한 후, 문제에서 원하는것은 10007로 나눈 나머지를 출력해야하기 때문에 각 값을 계산 할 때 마다 10007로 나눈 나머지로 값을 나누어주었다. 마지막에 10007로 값을 구하게 된다면, N = 1000일 때 값이 int 범위를 벗어난 경우가 되므로 N = 1000일 때의 값을 모두 구한 후 10007로 나눈 나머지를 출력하게 된다면 올바르지 않은 값을 출력하게 된다. 지속해서 나머지가 필요하다면, 미리 나머지를 구해놓아도 이후에 구한 나머지와 같으므로 미리 나머지를 구해 저장하는 방식으로 구현했다.
package backjoon;
import java.util.Scanner;
public class Two_multiple_n_Tiling_2 {
static int d[] = new int[1001];
public static int solve(int N){
if (N == 1) return (1);
else if (N == 2) return (3);
else if (d[N] > 0) return d[N];
else {
d[N] = (solve(N - 1) + solve(N - 2) * 2) % 10007;
return d[N];
}
}
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
System.out.println(solve(N));
}
}