나를 기록하다
article thumbnail
반응형

제곱수의 합

시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초128 MB51778208821518339.344%

문제

어떤 자연수 N은 그보다 작거나 같은 제곱수들의 합으로 나타낼 수 있다. 예를 들어 11=3^2+1^2+1^2(3개 항)이다. 이런 표현방법은 여러 가지가 될 수 있는데, 11의 경우 11=2^2+2^2+1^2+1^2+1^2(5개 항)도 가능하다. 이 경우, 수학자 숌크라테스는 “11은 3개 항의 제곱수 합으로 표현할 수 있다.”라고 말한다. 또한 11은 그보다 적은 항의 제곱수 합으로 표현할 수 없으므로, 11을 그 합으로써 표현할 수 있는 제곱수 항의 최소 개수는 3이다.

주어진 자연수 N을 이렇게 제곱수들의 합으로 표현할 때에 그 항의 최소개수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 100,000)

출력

주어진 자연수를 제곱수의 합으로 나타낼 때에 그 제곱수 항의 최소 개수를 출력한다.

예제 입력 1

7

예제 출력 1

4

예제 입력 2

1

예제 출력 2

1

예제 입력 3

4

예제 출력 3

1

예제 입력 4

11

예제 출력 4

3

예제 입력 5

13

예제 출력 5

2

풀이

n = int(input())
d = [0] * (n + 1)
for i in range(1, n+1):
    d[i] = i
    j = 1
    while j * j <= i:
        if d[i] > d[i - j * j] + 1:
            d[i] = d[i - j * j] + 1
        j += 1
print(d[n])

우선, 입력값 N을 받은 후, N을 나타내기 위한 최소 제곱수 항의 개수를 저장할 DP 리스트 d를 생성합니다. 이 리스트의 크기는 N+1입니다.

다음으로, for문을 이용하여 1부터 N까지 반복하며, DP 리스트 d를 갱신합니다. 안쪽 while문에서는 현재 i를 나타내기 위한 제곱수 j1부터 차례대로 증가시키며, DP 리스트 d를 갱신합니다.

이때, DP 리스트 d[i]i를 나타내기 위한 최소 제곱수 항의 개수를 저장하며, 초기값으로는 i입니다. 그리고, d[i - j * j] + 1의 값과 d[i]의 값 중 작은 값을 DP 리스트 d[i]에 저장합니다.

위와 같은 과정을 반복하면, DP 리스트 d[N]에는 N을 나타내기 위한 최소 제곱수 항의 개수가 저장됩니다. 따라서, DP 리스트 d[N]을 출력하면 문제에서 요구하는 정답을 얻을 수 있습니다.

이 코드의 시간 복잡도는 O(N*sqrt(N))입니다. 이는 N이 커질수록 계산 시간이 길어지는 단점이 있지만, DP 알고리즘의 특성상 중복 계산을 피할 수 있어 보다 효율적인 계산이 가능합니다.


Uploaded by N2T

반응형
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...