[백준 1699] 제곱수의 합 ❗
https://www.acmicpc.net/problem/1699
🥚문제
🥚입력/출력
🍳코드
import sys
import math
input = sys.stdin.readline
n = int(input().strip())
dp = [0]*(n+1)
# bottom-up 방식
def bottom_up(n):
# 제곱수는 1로 초기화
x = 1
while x*x <= n:
dp[x*x] = 1
x += 1
# n의 값이 0이 아니면(제곱수) 리턴
if dp[n] != 0:
return dp[n]
for i in range(1, n+1):
if dp[i] != 0:
continue
mini = i
# j*j <= i인 것 중
# dp[j*j] + dp[i-j*j]의 값이 최소인 것을
# dp[i]의 값으로 갱신
for j in range(1, int(math.sqrt(i)) + 1):
if 1 + dp[i-j*j] < mini:
mini = 1 + dp[i-j*j] # 1 = dp[j*j]
dp[i] = mini
return dp[n]
print(bottom_up(n))
🧂아이디어
다이나믹 프로그래밍
- top-down으로 풀면 n이 커졌을 때 recursion error를 뱉어내서 bottom-up으로 풀이!
- dp[x] : 자연수 x를 제곱수의 합으로 표현할 때 그 항의 최소 개수를 저장
- x가 이미 제곱수일 때 (x = y*y (1 <= y < x) )
- x를 제곱수의 합으로 표현했을 때 x = y^2이므로 항이 1개
- 따라서 이미 제곱수인 x들(1, 4, 9, ...)에 대해 dp[x] = 1로 초기화 해준다
- x가 제곱수가 아닐 때 (2, 3, 5, 6, 7, 8, 10, 11, ...)
- 우리의 목표는 항의 개수를 최소로 만드는 것이기 때문에 dp에 저장된 값이 "1"인 제곱수들을 활용하여 식을 만들어낼 것이다.
- y*y <= x 인 모든 제곱수, y*y에 대하여
- 1 + dp[x-y*y] (= dp[y*y] + dp[x - y*y] )를 한 값 중 최소값을 dp[x]에 저장한다.
Author And Source
이 문제에 관하여([백준 1699] 제곱수의 합 ❗), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@eastgloss0330/백준-1699-제곱수의-합
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
- x를 제곱수의 합으로 표현했을 때 x = y^2이므로 항이 1개
- 따라서 이미 제곱수인 x들(1, 4, 9, ...)에 대해 dp[x] = 1로 초기화 해준다
- 우리의 목표는 항의 개수를 최소로 만드는 것이기 때문에 dp에 저장된 값이 "1"인 제곱수들을 활용하여 식을 만들어낼 것이다.
- y*y <= x 인 모든 제곱수, y*y에 대하여
- 1 + dp[x-y*y] (= dp[y*y] + dp[x - y*y] )를 한 값 중 최소값을 dp[x]에 저장한다.
Author And Source
이 문제에 관하여([백준 1699] 제곱수의 합 ❗), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@eastgloss0330/백준-1699-제곱수의-합저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)