Dynamic Programming 백준 알고리즘 자바 1699 ‘제곱수의 합’ 문제풀이

1 minute read

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]);
	}
}

Tags:

Updated: