끄적끄적 코딩
article thumbnail

다이나믹 프로그래밍 문제입니다.

1. 2*1의 경우 2가지 경우가 가능합니다.
1-1. 2*1 타일 1개
1-2. 1*1 타일 2개

2*2의 경우 3가지 경우가 가능합니다.
2-1. 1*2 타일 2개
2-2. 1*2 타일 1개(위), 1*1 타일 2개 (아래)
2-3. 1*2 타일 2개(아래), 1*1 타일 2개 (위)

이를 통해 점화식을 세울수 있습니다.

DP[i] = DP[i-1] * 2 + DP[i-2] * 3


여기서 예외인 부분이 존재합니다.
3. 2*3의 경우

3-1.  ㅁㅁ-
        -ㅁㅁ

3-2.  -ㅁㅁ
      ㅁㅁ-


(ㅁㅁ 1*2 타일)
( - 1*1 타일)

위와 같은 모양이 가능합니다.
해당 모양은 2*4, 2*5 ... 2*n 모두 가능한 모양입니다.

그래서 DP를 2차원 배열로 만들어서 2번째 부분에는 위의 값을 계산하도록 하였습니다.
위의 모양은 3개이상의 공간이 있을 때 가능하므로
(3칸 전의 경우의 수 + 1칸 전의 (3.) 경우의 수) * 2 로 계산할 수 있습니다.

점화식으로 나타내면 다음과 같습니다.

DP[i][1] = (DP[i-1][1] + DP[i-3][0]) * 2

 

#include <iostream>
#define MOD 1000000007
typedef long long ll;
using namespace std;

ll DP[1000001][2];

void solution()
{
  int n;

  cin >> n;

  DP[0][0] = 0;
  DP[1][0] = 2;
  DP[2][0] = 7;
  DP[2][1] = 1;

  for (int i = 3; i <= n; ++i)
  {
    DP[i][1] = (DP[i - 3][0] + DP[i - 1][1]) % MOD;
    DP[i][0] = (DP[i][1] * 2 + DP[i - 1][0] * 2 + DP[i - 2][0] * 3) % MOD;
  }

  cout << DP[n][0] << endl;
}

int main(int argc, char *argv[])
{
  solution();

  return 0;
}

'알고리즘' 카테고리의 다른 글

[C++] 백준 1562번 계단 수  (0) 2021.03.31
[C++] 백준 18119번 단어 암기  (0) 2021.03.29
[C++] 백준 2098번 외판원 순회  (0) 2021.03.24
[C++] 백준 2234번 성곽  (0) 2021.03.22
[C++] 백준 1062번 가르침  (0) 2021.03.14

검색 태그