[boj] 2133. 타일 채우기 (node.js)

호이·2022년 6월 1일
0

algorithm

목록 보기
71/77
post-thumbnail

문제

[boj] 2133. 타일 채우기 (node.js)

  • 벽의 가로 길이가 주어진다. 이때, 주어진 타일로 채울 수 있는 경우의 수를 구하는 문제

핵심 풀이

  • 홀수인 경우 완성할 수 있는 경우가 존재하지 않으므로 0으로 초기화한다.
  • 짝수인 경우만 고려한다.
  • 해를 구하기 위해 경우의 수를 생각해보면, 타일로 완성시킬 수 있는 최소 단위는 벽의 가로길이가 2일 때이며, (짝수인 경우) 무한정으로 새로운 조합으로 벽을 채울 수 있다!

단계별로 생각하기

2133

for (let i = 3; i <= N; i++) {
  if (i % 2 == 0) {
    dp[i] = dp[i - 2] * 3
    for (let j = 4; j <= i; j += 2) dp[i] += dp[i - j] * 2
  } else dp[i] = 0
}
  • 2일 때 채울 수 있는 경우의 수는 총 3이다. 이를 dp배열에 저장하면 dp[2] = 3
  • 그 뒤로 짝수인 4, 6, 8, … 을 쭉 생각해볼 수 있는데, 먼저 dp[4]가 될 수 있는 경우는 앞서 구한 2칸을 채울 수 있는 경우의 수인 3을 활용해서 dp[4 - 2] * 3으로 세울 수 있다. 거기다가 4칸을 채울 수 있는 경우의 수 1가지가 새롭게 등장하며, 이를 상하 반전시킬 수 있으므로 최종점화식은 아래와 같다.
  • dp[4] = dp[4-2] 3 + dp[4 - 4] 2
  • 이 계산을 위해 dp[0] = 1로 초기화해준다.
  • 다음으로 6을 생각해보면, 마찬가지로 dp[6] = dp[6 - 2] 3 + dp[6 - 4] 2 이다. 여기서 한 단계 더 생각해보면, 모든 짝수 값이 주어질 때마다 새롭게 전체 크기를 채울 수 있는 모양이 생긴다. 즉, 6칸짜리를 채울 수 있으며 상하반전이 가능하므로 최종 점화식은 dp[6] = dp[6 - 2] 3 + dp[6 - 4] 2 + dp[6 - 6] * 2 이다.
  • dp[i] = dp[i - 2] * 3 + dp[i - 4] * 2 + … + dp[0] * 2

전체 풀이

const readline = require("readline")
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
})

const solution = () => {
  const N = input()
  const dp = [1, 0, 3]
  for (let i = 3; i <= N; i++) {
    if (i % 2 == 0) {
      dp[i] = dp[i - 2] * 3
      for (let j = 4; j <= i; j += 2) dp[i] += dp[i - j] * 2
    } else dp[i] = 0
  }
  console.log(dp[N])
}

let line = 0
const input = () => stdin[line++]

let stdin = []
rl.on("line", function (line) {
  stdin.push(line)
}).on("close", function () {
  solution()
  process.exit()
})
profile
매일 부활하는 개복치

0개의 댓글