넘치게 채우기

[BOJ] 2718 - 타일 채우기 본문

PS/BOJ

[BOJ] 2718 - 타일 채우기

riveroverflow 2025. 3. 4. 13:40
728x90
반응형

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

BOJ - 타일 채우기

문제 유형: 다이나믹 프로그래밍

문제 난이도: Gold I

시간 제한: 1초

메모리 제한: 128MB

 

문제

4*N 크기의 타일을 2*1, 1*2 크기의 도미노로 완전히 채우려고 한다. 예를 들어 4*2 타일을 채우는 방법은 다음과 같이 5가지가 있다.

N이 주어졌을 때, 타일을 채우는 방법의 개수를 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. T는 1,000보다 작거나 같은 자연수이다. 각 테스트 케이스는 정수 하나로 이루어져 있다. 이 정수는 문제에서 설명한 타일의 너비 N이다. N은 자연수이다.

N은 타일을 채우는 경우의 수가 2,147,483,647 이하이도록 주어진다.

 

출력

각 테스트 케이스에 대해 4*N크기의 타일을 채우는 방법의 경우의 수를 출력한다.

 

풀이

참조(이 영상에서는 3 x n의 타일링을 다루지만, 영상을 보신다면 이해가 편하실겁니다):

https://www.youtube.com/watch?v=yn2jnmlepY8

 

 

dp[i][상태]를 i+1행기준 현재 상태를 만들 수 있는 방법의 경우의 수라고 하자.

아래 그림처럼 상태를 정의하고 전이식을 유도할 수 있다:

 

m = 가장 큰 입력이라고 하고,

dp[m]까지 완성한 뒤,

각 요소에 대해 dp[i][0]을 반환해주면 된다.

 

코드

C++

#include <bits/stdc++.h>

using namespace std;

int main(int argc, char *argv[]) {
    int n;
    cin >> n;
    vector<int> queries(n);

    for (int i = 0; i < n; ++i) {
        cin >> queries[i];
    }
    int m = *max_element(queries.begin(), queries.end());
    vector<vector<int>> dp(m + 1, vector<int>(16, 0));

    dp[0][0] = 1;
    dp[0][5] = 1;
    dp[0][8] = 1;
    dp[0][10] = 1;
    dp[0][15] = 1;

    for (int i = 1; i <= m; i++) {
        dp[i][0] = dp[i - 1][15];

        dp[i][1] = dp[i - 1][14];

        dp[i][2] = dp[i - 1][13];

        dp[i][3] = dp[i - 1][12];

        dp[i][4] = dp[i - 1][11];

        dp[i][5] = dp[i - 1][10] + dp[i - 1][15];

        dp[i][6] = dp[i - 1][9];

        dp[i][7] = dp[i - 1][8];

        dp[i][8] = dp[i - 1][7] + dp[i - 1][15];

        dp[i][9] = dp[i - 1][6];

        dp[i][10] = dp[i - 1][15] + dp[i - 1][5];

        dp[i][11] = dp[i][1] + dp[i][3] + dp[i - 1][4];

        dp[i][12] = dp[i][4] + dp[i - 1][3];

        dp[i][13] = dp[i][1] + dp[i - 1][2];

        dp[i][14] = dp[i - 1][1] + dp[i][2] + dp[i][4];

        dp[i][15] = dp[i - 1][15] + dp[i][7] + dp[i - 1][0] + dp[i - 1][5] +
                    dp[i - 1][10];
    }

    // output..
    for (const auto &q : queries) {
        cout << dp[q][0] << "\n";
    }

    return 0;
}

 

728x90
반응형

'PS > BOJ' 카테고리의 다른 글

[BOJ] 1451 - 직사각형으로 나누기  (0) 2025.03.06
[BOJ] 2313 - 보석 구매하기  (0) 2025.03.05
[BOJ] 1388 - 바닥 장식  (0) 2025.03.03
[BOJ] 12755 - 수면 장애  (0) 2025.03.02
[BOJ] 13021 - 공 색칠하기  (0) 2025.03.01