Dynamic Programming 백준 알고리즘 자바 1699 ‘제곱수의 합’ 문제풀이
Problem
어떤 자연수 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을 이렇게 제곱수들의 합으로 표현할 때에 그 항의 최소개수를 구하는 프로그램을 작성하시오.
Input
첫째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 100,000)
Output
주어진 자연수를 제곱수의 합으로 나타낼 때에 그 제곱수 항의 최소 개수를 출력한다.
Solution
점화식 찾기까지 너무 힘든 것 같다… 일단 한 숫자를 만들 수 있는 모든 경우의 수를 풀어 쓴 후, 이전 수와 닮은 꼴을 찾는다. 예제 11을 보면, 2^2+2^2+1^2+1^2+1^2 이는 2^2+7(2^2+1^2+1^2+1^2) 과 같고, 3^2+1^2+1^2은 3^2+3(1^2+1^2)와 같다. 따라서 d[11]은 d[7]+1과 d[2]+1 중 적은 값이다. 이때 7은 11에서 2^2=4를 뺀 값이고, 2는 11에서 3^2=9를 뺀 값이다.
Code
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int n = scan.nextInt(); int[] dp = new int[n+1]; dp[1] = 1; for(int i = 2; i < n+1; i++) { dp[i] = i; for(int j = 1; j*j <= i; j++) dp[i] = Math.min(dp[i], dp[i-j*j] + 1); } System.out.println(dp[n]); } }