πŸ§‘πŸ»‍πŸ’» Coding Test/πŸ–ŒοΈ BAEKJOON

[ BAEKJOON ] 1, 2, 3 λ”ν•˜κΈ° 4 / 15989 / Python

EarthSea 2025. 1. 7. 13:08

 

 

문제

μ •μˆ˜ 4λ₯Ό 1, 2, 3의 ν•©μœΌλ‘œ λ‚˜νƒ€λ‚΄λŠ” 방법은 총 4κ°€μ§€κ°€ μžˆλ‹€. 합을 λ‚˜νƒ€λ‚Ό λ•ŒλŠ” 수λ₯Ό 1개 이상 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. 합을 이루고 μžˆλŠ” 수의 μˆœμ„œλ§Œ λ‹€λ₯Έ 것은 같은 κ²ƒμœΌλ‘œ μΉœλ‹€.

  • 1+1+1+1
  • 2+1+1 (1+1+2, 1+2+1)
  • 2+2
  • 1+3 (3+1)

μ •μˆ˜ n이 μ£Όμ–΄μ‘Œμ„ λ•Œ, n을 1, 2, 3의 ν•©μœΌλ‘œ λ‚˜νƒ€λ‚΄λŠ” λ°©λ²•μ˜ 수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ 개수 Tκ°€ μ£Όμ–΄μ§„λ‹€. 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λŠ” ν•œ μ€„λ‘œ 이루어져 있고, μ •μˆ˜ n이 μ£Όμ–΄μ§„λ‹€. n은 μ–‘μˆ˜μ΄λ©° 10,000보닀 μž‘κ±°λ‚˜ κ°™λ‹€.

좜λ ₯

각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ§ˆλ‹€, n을 1, 2, 3의 ν•©μœΌλ‘œ λ‚˜νƒ€λ‚΄λŠ” λ°©λ²•μ˜ 수λ₯Ό 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1

3
4
7
10

예제 좜λ ₯ 1

4
8
14

λ‚˜μ˜ 풀이

문제 μ„€λͺ… 및 ν•΄κ²° 방법

이 λ¬Έμ œλŠ” DP(Dynamic Programming)둜 ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€λ§Œ, 점화식을 λ„μΆœν•˜λŠ” 과정이 μ–΄λ €μ› λ˜ κ΄€κ³„λ‘œ 인터넷을 μ°Έκ³ ν•˜μ—¬ 문제λ₯Ό ν•΄κ²°ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

문제 쑰건

1, 2, 3λ§Œμ„ μ‚¬μš©ν•˜μ—¬ μ£Όμ–΄μ§„ 숫자λ₯Ό λ§Œλ“œλŠ” λ°©λ²•μ˜ 수λ₯Ό κ΅¬ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ μ€‘μš”ν•œ 점은 같은 숫자 쑰합이라도 μˆœμ„œκ°€ λ‹€λ₯΄λ©΄ λ™μΌν•œ 경우둜 κ°„μ£Όν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, 1+1+2와 1+2+1은 같은 μ‘°ν•©μœΌλ‘œ λ΄…λ‹ˆλ‹€. λ”°λΌμ„œ μ‘°ν•©μ˜ 숫자λ₯Ό μ˜€λ¦„μ°¨μˆœμœΌλ‘œ λ‚˜μ—΄ν•΄ 문제λ₯Ό ν•΄κ²°ν•©λ‹ˆλ‹€.

 

 

예제: 숫자 7을 λ§Œλ“œλŠ” 경우

숫자 7을 1, 2, 3을 μ΄μš©ν•΄ λ§Œλ“œλŠ” 경우λ₯Ό λ‚˜μ—΄ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • 1+1+1+1+1+1+1
  • 1+1+1+1+1+2
  • 1+1+1+2+2
  • 1+2+2+2
  • 1+1+1+1+3
  • 1+1+2+3
  • 2+2+3
  • 1+3+3

이처럼, λ§ˆμ§€λ§‰ μˆ«μžκ°€ λͺ‡μΈμ§€μ— 따라 μ‘°ν•©μ˜ μ œμ•½μ΄ λ‹¬λΌμ§‘λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

  • λ§ˆμ§€λ§‰ μˆ«μžκ°€ 2라면, μ•žμ˜ μˆ«μžλŠ” 2 μ΄ν•˜λ§Œ κ°€λŠ₯ν•©λ‹ˆλ‹€. (3이 올 수 μ—†μŒ)
  • λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1이라면, λͺ¨λ“  μˆ«μžκ°€ 1둜만 이루어진 쑰합이 λ©λ‹ˆλ‹€.

 

점화식 λ„μΆœ κ³Όμ •

μž‘μ€ μˆ«μžλΆ€ν„° μ μ§„μ μœΌλ‘œ 경우의 수λ₯Ό κ³„μ‚°ν•˜λŠ” λ°”ν…€μ—… λ°©μ‹μœΌλ‘œ ν•΄κ²°ν•©λ‹ˆλ‹€.

숫자 n을 λ§Œλ“œλŠ” 경우의 수λ₯Ό dp[n]이라 μ •μ˜ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ dp[n][k]λŠ” 숫자 n을 λ§Œλ“€ λ•Œ λ§ˆμ§€λ§‰ μˆ«μžκ°€ k인 경우의 수λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

 

κΈ°λ³Έ κ·œμΉ™

  1. 숫자 n을 λ§Œλ“œλŠ” λ°©λ²•μ˜ 총 경우의 μˆ˜λŠ”, dp[n][1], dp[n][2], dp[n][3]의 ν•©μž…λ‹ˆλ‹€.
    즉, dp[n]=dp[n][1]+dp[n][2]+dp[n][3]
  2. dp[n][k]λŠ” λ‹€μŒκ³Ό 같이 κ³„μ‚°λ©λ‹ˆλ‹€.
    • λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1인 경우: dp[n][1]=dp[n−1][1]
    • λ§ˆμ§€λ§‰ μˆ«μžκ°€ 2인 경우: dp[n][2]=dp[n−2][1]+dp[n−2][2]
    • λ§ˆμ§€λ§‰ μˆ«μžκ°€ 3인 경우: dp[n][3]=dp[n−3][1]+dp[n−3][2]+dp[n−3][3]

 

ν‘œλ‘œ λ³΄λŠ” κ³Όμ • μ˜ˆμ‹œ

μ•„λž˜ ν‘œλŠ” 숫자λ₯Ό 1~7κΉŒμ§€ λ§Œλ“€κΈ° μœ„ν•œ 경우의 수λ₯Ό κ³„μ‚°ν•œ 과정을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.

숫자 λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1인 경우 λ§ˆμ§€λ§‰ μˆ«μžκ°€ 2인 경우 λ§ˆμ§€λ§‰ μˆ«μžκ°€ 3인 경우 dp[n]
1 1 0 0 1
2 1 1 0 2
3 1 1 1 3
4 1 2 1 4
5 1 2 2 5
6 1 3 3 7
7 1 3 4 8

 

μ˜ˆμ‹œ 풀이

숫자 7을 κ΅¬ν•˜λŠ” 방법을 예둜 λ“€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

  1. λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1인 경우:숫자 6을 λ§Œλ“€ λ•Œ λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1인 κ²½μš°μ— 1을 λ”ν•˜λ©΄ λ©λ‹ˆλ‹€.
    λ”°λΌμ„œ, dp[7][1]=dp[6][1]=1
  2. λ§ˆμ§€λ§‰ μˆ«μžκ°€ 2인 경우:숫자 5λ₯Ό λ§Œλ“€ λ•Œ λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1 λ˜λŠ” 2인 κ²½μš°μ— 2λ₯Ό λ”ν•˜λ©΄ λ©λ‹ˆλ‹€.
    λ”°λΌμ„œ, dp[7][2]=dp[5][1]+dp[5][2]=1+2=3
  3. λ§ˆμ§€λ§‰ μˆ«μžκ°€ 3인 경우:숫자 4λ₯Ό λ§Œλ“€ λ•Œ λ§ˆμ§€λ§‰ μˆ«μžκ°€ 1, 2, 3인 κ²½μš°μ— 3을 λ”ν•˜λ©΄ λ©λ‹ˆλ‹€.
    λ”°λΌμ„œ, dp[7][3]=dp[4][1]+dp[4][2]+dp[4][3]=1+2+1=4
  4. 숫자 7의 총 경우의 수: dp[7]=dp[7][1]+dp[7][2]+dp[7][3]=1+3+4=8

 


 

μ½”λ“œ

μœ„ 점화식을 λ°”νƒ•μœΌλ‘œ DP 배열을 μ±„μš°λ©΄, 숫자 n을 λ§Œλ“œλŠ” λͺ¨λ“  경우의 수λ₯Ό 효율적으둜 ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

이λ₯Ό μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

tc = int(input())
arr = list()
for _ in range(tc):
    arr.append(int(input()))

mx = max(arr)

# DP λ§Œλ“€κΈ°
dp = list()
for _ in range(mx):
    dp.append([0] * 3)

dp[0][0] = 1
dp[1][0] = 1
dp[1][1] = 1
dp[2][0] = 1
dp[2][1] = 1
dp[2][2] = 1

# 점화식에 μ˜ν•œ 계산
if mx > 2:
    for i in range(3, mx):
        dp[i][2] = dp[i-3][2] + dp[i-3][1] + dp[i-3][0]
        dp[i][1] = dp[i-2][1] + dp[i-2][0]
        dp[i][0] = dp[i-1][0]

# μ •λ‹΅
for i in arr:
    print(dp[i-1][0] + dp[i-1][1] + dp[i-1][2])