🧩 Problem Solving/[λ°±μ€€]

[λ°±μ€€] 17626 Four Squares (python 파이썬)

μ œλ΄‰μ•„ 2022. 7. 5. 21:20

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

 

17626번: Four Squares

λΌκ·Έλž‘μ£ΌλŠ” 1770년에 λͺ¨λ“  μžμ—°μˆ˜λŠ” λ„· ν˜Ήμ€ κ·Έ μ΄ν•˜μ˜ 제곱수의 ν•©μœΌλ‘œ ν‘œν˜„ν•  수 μžˆλ‹€κ³  증λͺ…ν•˜μ˜€λ‹€. μ–΄λ–€ μžμ—°μˆ˜λŠ” 볡수의 λ°©λ²•μœΌλ‘œ ν‘œν˜„λœλ‹€. 예λ₯Ό λ“€λ©΄, 26은 52κ³Ό 12의 합이닀; λ˜ν•œ 42 + 32 + 1

www.acmicpc.net


아이디어

1. 그리디와 dp

  • μ²˜μŒμ—λŠ” n을 λ„˜μ§€ μ•ŠλŠ” μ΅œλŒ€ 제곱수λ₯Ό n에 λΉΌκ°€λ©΄ λ˜μ§€ μ•Šμ„κΉŒ μƒκ°ν–ˆλ‹€.
  • μ΄λ ‡κ²Œ ν•˜λ©΄ μ˜ˆμ™Έκ°€ 생긴닀. 예λ₯Ό λ“€μ–΄ 12λŠ” κ·Έλ¦¬λ””λ‘œ μƒκ°ν•˜λ©΄ 9, 1, 1, 1μ΄μ§€λ§Œ 정닡은 4,4,4둜 3κ°œκ°€ μ΅œμ†Œ κ°œμˆ˜λ‹€.  
  •  λ‹€μ‹œ 문제 λ‚΄μš©μ„ 보고 dp둜 ν’€κΈ°λ‘œ κ²°μ •
  • DP[n] = (nμ΄λΌλŠ” 수λ₯Ό λ§Œλ“œλŠ”λ° ν•„μš”ν•œ 수의 개수)

μ½”λ“œ μ„€λͺ…

k = 1
while k**2 <= n:
    DP[k**2] = 1
    k += 1

λ¨Όμ € DPλ¦¬μŠ€νŠΈμ— μ œκ³±μˆ˜λ“€μ„ μ €μž₯ν•΄μ€€λ‹€. 1, 4, 9... λŠ” μ œκ³±μˆ˜μ΄λ―€λ‘œ 무쑰건 μ΅œμ†Œ κ°œμˆ˜λŠ” 1이닀.

 

for i in range(1, n + 1):
    if DP[i] != 0:
        continue
    j = 1
    while j*j <= i:
        if DP[i] == 0:
            DP[i] = DP[j*j] + DP[i - j*j]
        else:
            DP[i] = min(DP[i], DP[j*j] + DP[i - j*j])
        j += 1

nκΉŒμ§€ for문을 μ‹€ν–‰ν•œλ‹€. DP에 이미 값이 μ‘΄μž¬ν•˜λ©΄(= 제곱수 라면) continue ν•΄μ€€λ‹€. 

 

DP에 값이 μ—†λ‹€λ©΄ iλ₯Ό λ„˜μ§€ μ•ŠλŠ” μ œκ³±μˆ˜κΉŒμ§€ λ°˜λ³΅ν•΄μ£Όλ©΄ λœλ‹€.

 

예λ₯Ό λ“€μ–΄ iκ°€ 12라면

DP[12] = DP[1] + DP[11]λ₯Ό λ¨Όμ € μ €μž₯ν•΄μ€€λ‹€.

μ΄ν›„μ—λŠ” 

DP[4] + DP[8], DP[9] + DP[3]κ³Ό λΉ„κ΅ν•΄μ„œ μ΅œμ†Ÿκ°’μ„ μ €μž₯ν•΄μ€€λ‹€.

μ—¬κΈ°μ„œ μ œκ³±μˆ˜λ“€μ€ μ „λΆ€ 1μ΄λ―€λ‘œ DP[i] = min(DP[i - j * j]) + 1 (j*j <= i)라고 μƒκ°ν•˜λ©΄ λœλ‹€.


전체 μ½”λ“œ

 

n = int(input())
count = 0

DP = [0] * (n + 1)

k = 1
while k**2 <= n:
    DP[k**2] = 1
    k += 1

for i in range(1, n + 1):
    if DP[i] != 0:
        continue
    j = 1
    while j*j <= i:
        if DP[i] == 0:
            DP[i] = DP[j*j] + DP[i - j*j]
        else:
            DP[i] = min(DP[i], DP[j*j] + DP[i - j*j])
        j += 1
print(DP[n])