
2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오.
아래 그림은 2×5 크기의 직사각형을 채운 한 가지 방법의 예이다.
첫째 줄에 n이 주어진다. (1 ≤ n ≤ 1,000)
해당 문제는 2×N 크기의 직사각형을 1×2, 2×1 크기의 타일들로 채우는 방법의 수를 구하는 문제이다.
이 문제는 DP(Dynamic Programming)를 활용하여 해결 할 수 있다. N=1일 경우부터 N=3인 경우까지를 각각 그림으로 살펴보자.
먼저 N=1인 경우를 생각해 보면 1×2 타일 하나로 직사각형을 채울 수 있으므로 방법의 수는 1이다. 이를 그림으로 나타내면 다음과 같다.
다음으로 N=2인 경우에는 1×2 타일을 2개 사용하거나 2×1 타일 2개 사용하여 직사각형을 채울 수 있으므로 방법의 수는 2이다.
마지막으로 N=3인 경우를 살펴 보면 N=2인 직사각형에 1×2 타일 하나를 추가하는 경우와 N=1인 직사각형에 2×1 타일 2개를 추가하는 경우를 고려할 수 있다. 그림으로 나타내면 다음과 같다.
이러한 규칙을 점화식으로 나타내면 다음과 같다.
dp[N] = dp[N-1] + dp[N-2]
해당 점화식이 맞는지 확인하기 위해서 N=1부터 N=5까지의 개수를 손수 구해보면 다음과 같다.
1, 2, 3, 5, 8
구한 수열에서도 점화식이 성립하는 것을 알 수 있다. 피보나치 수열과 같은 결과라는 것 또한 알 수 있다.
따라서 찾아낸 점화식을 코드로 구현하면 해당 문제를 해결 할 수 있다.
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 가로 길이 입력
int N = Integer.parseInt(br.readLine());
int[] dp = new int[N + 2];
// 첫 항 설정
dp[1] = 1;
// 점화식에 따라 dp배열 업데이트
for(int i = 2; i <= N + 1; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
dp[i] %= 10007;
}
// 정답 출력
System.out.print(dp[N + 1]);
}
}
#include <iostream>
#include <cstring>
#define fastio ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr)
#define endl '\n'
using namespace std;
int main() {
fastio;
// 가로 길이 입력
int N;
cin >> N;
int dp[N + 2];
memset(dp, 0, sizeof(dp));
// 첫 항 설정
dp[1] = 1;
// 점화식에 따라 dp배열 업데이트
for(int i = 2; i <= N + 1; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
dp[i] %= 10007;
}
// 정답 출력
cout << dp[N + 1] << endl;
return 0;
}
fun main(args: Array<String>) = with(System.`in`.bufferedReader()) {
// 가로 길이 입력
var N = readLine().toInt()
var dp = Array<Int>(N + 2, {0})
// 첫 항 설정
dp[1] = 1
// 점화식에 따라 dp배열 업데이트
for (i in 2 .. N + 1) {
dp[i] = dp[i - 1] + dp[i - 2]
dp[i] %= 10007
}
// 정답 출력
println(dp[N + 1])
}
from sys import stdin
def main():
# 가로 길이 입력
N = int(stdin.readline())
dp = [0] * (N + 2)
# 첫 항 설정
dp[1] = 1
# 점화식에 따라 dp배열 업데이트
for i in range(2, N + 2):
dp[i] = dp[i - 1] + dp[i - 2]
dp[i] = dp[i] % 10007
# 정답 출력
print(dp[N + 1])
if __name__ == "__main__":
main()
import Foundation
func main() {
// 가로 길이 입력
var N = Int(readLine()!)!
var dp = [Int](repeating: 0, count: N + 2)
// 첫 항 설정
dp[1] = 1
// 점화식에 따라 dp배열 업데이트
for i in 2..<N + 2 {
dp[i] = dp[i - 1] + dp[i - 2]
dp[i] %= 10007
}
// 정답 출력
print(dp[N + 1])
}
main()
