Algorithm/Baekjoon

[백준] 1699 제곱수의 합 파이썬 python

rrojin 2022. 2. 14. 12:23

문제링크

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

 

1699번: 제곱수의 합

어떤 자연수 N은 그보다 작거나 같은 제곱수들의 합으로 나타낼 수 있다. 예를 들어 11=32+12+12(3개 항)이다. 이런 표현방법은 여러 가지가 될 수 있는데, 11의 경우 11=22+22+12+12+12(5개 항)도 가능하다

www.acmicpc.net

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import sys
input = sys.stdin.readline
 
= int(input())
= list(range(100001))
 
for i in range(4,n+1):
    if int(i**(1/2))**2 == i:
        d[i] = 1
        pass
    tmp = d[i]
    for j in range(1,i//2+1):
        if tmp>d[j]+d[i-j]:
            tmp = d[j]+d[i-j]
    d[i] = tmp 
print(d[n])
cs

 

POINT

- DP로 접근
- 풀이방법:
'd[i] = i를 그 합으로써 표현할 제곱수 항의 최소 개수' 로 정의한다. 
ex) d[4] = 1 (4=2^2), d[5] = 2 (5=2^2+1^2), d[6] = 3 (6=2^2+1^2+1^2),
d[10]=2 (10 = 3^2+1^2)
 
 
이후, DP를 적용하여 다음과 같은 과정을 거친다.
5를 만들기 위해선, 5 자체가 제곱수인가 vs 5 = 1+4 vs 5 = 2+3 중 비교하기!
 
5가 제곱수인가?(=1) vs d[1]+d[4]+ vs d[2]+d[3] 중 최소로 갱신
6이 제곱수?(=1) vs d[1]+d[5]+ vs d[2]+d[4]+ vs d[3]+d[3] 중 최소로 갱신 
 
 
* 완전제곱수 판별 방법
(i**(1/2))**2 == i 으로 하면 파이썬 내부 버림 때문에 11과 같은 수도 제곱수로 오판된다. 
따라서, int()를 활용하여  int(i**(1/2))**2 == i 다음과 같이 해결한다.