본문 바로가기
알고리즘/백준

C++ 백준 BOJ 11726 2 x n 타일링

by parkkingcar 2022. 12. 19.

 

2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하는 문제입니다.

 

 

자주 접할 수 있는 DP문제(다이나믹 프로그래밍) 유형입니다.

 

보통 DP문제는 피보나치 수열, 재귀함수 등을 이용하여 해결 가능합니다.

 

 

 

11726번: 2×n 타일링

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

www.acmicpc.net

#include <iostream>
using namespace std;
int dp[1001];
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
  
    int num;
    cin >> num;
    
    dp[1]=1;
    dp[2]=2;
    for(int i=3; i<=num; i++){
        dp[i] = dp[i-1]+dp[i-2];
        dp[i]%=10007;
    }
    
    cout << dp[num];
    return 0;
}

 

 

DP문제임을 파악하면 규칙을 찾아내어 함수를 쉽게 유추할 수 있습니다.

 

먼저 타일이 n개일 때,  2 x 1모양의 타일을 붙이는 가지수를 f(n)이라 가정합니다.

 

그러면 n=1일 때 , 2 x 1에서는 하나의 타일만 들어가므로

" l "

f(1) = 1

 

 

n=2 일 때, 2 x 2 아래처럼 두가지 경우로

" l l ", " = "

f(2) = 2

 

n=3 일 때,  

" lll " , " l= ", " =l "

f(3) = 3

n=4 일 때,  

" llll ", " l=l ", " =ll ", " ll= ", == "

f(4) = 5

 

여기서 n=4 인 경우를 생각해보면,

 

" llll ", " l=l ", " =ll " 이 경우 n=3인 경우에서 제일 오른쪽에 2 x 1 타일을 하나 붙인 것과 모양이 같습니다.

 

즉, 2 x 1 타일 하나가 맨 왼쪽에 고정되어 있다고 볼 수 있습니다.

 

이를 다시 생각하면 맨 오른쪽에는 2 x 2 타일을 고정시키는 경우의 수로 볼 수 있습니다.

 

여기서 순열에 원리를 이용하여 한자리가 고정된 경우의 수를 (n-1)! 으로 보고 이를 적용시키면 됩니다.

 

 

 

따라서  2 x 1, 2 x 2의 경우의 수를 이용하여 dp 배열의 값을 선언합니다.

dp[1]=1,  dp[2]=2

 

이후 dp[i] = dp[i-1] + dp[i-2] 로 나머지 배열을 완성하면 됩니다.

 

 

( 재귀함수를 이용할 수 있지만 시간초과)

 

 

 

 

.

.

.

한국항공대학교 2022-2 알고리즘 설계 해석 기말고사 5번문제

댓글