Algorithm/백준 문제풀이

[백준] 17626 Four Squares - Java

너지살 2024. 2. 7. 18:10

 

 

 

문제 출저

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

 

17626번: Four Squares

라그랑주는 1770년에 모든 자연수는 넷 혹은 그 이하의 제곱수의 합으로 표현할 수 있다고 증명하였다. 어떤 자연수는 복수의 방법으로 표현된다. 예를 들면, 26은 52과 12의 합이다; 또한 42 + 32 + 1

www.acmicpc.net

 

 

 

문제 풀이

자연수의 숫자 n이 주어진다.

이 n을 제곱수로 표현할 때, 제곱수의 최소 갯수를 구해야 한다.

제곱수란 1, 4, 9  ... 와 같은 자연수의 제곱으로 만드는 숫자이다. 

 

 

DP를 이용해서 풀었습니다. 

n의 범위는 1부터 50,000 입니다. int[] dp = new int[50001]을 선언했습니다.

dp 배열에 각 숫자의 제곱수의 최소값을 업데이트하여 최소값을 구했습니다. 

최소값은 이중 포문을 이용해서 구했습니다. 

50000의 이하의 최대 제곱수는 223의 제곱인 49729입니다.

1부터 223까지의 제곱수를 구해 int d에 저장했습니다.

그 다음 d부터 50000까지 인덱스를 탐색하여 dp[j] = Math.min(dp[j], dp[j-d] + 1) 연산을 통해 최소 제곱수 값을 업데이트 했습니다. 

이 과정을 거치면 dp[n]으로 정답을 구할 수 있습니다.

 

 

 

소스 코드



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/*
Four Squares
https://www.acmicpc.net/problem/17626

재료는 제곱수

시간복잡도 : 50000 * 223 = 11,150,000 (대략 천만)
1초 = 1억번 연산 (10^8)
0.5초 = 5천만

시간 복잡도가 충분하다.


 */

public class Main {

    static int[] dp;

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        dp = new int[50001];
        for(int i = 1; i < 50001; i++) {
            dp[i] = i;
        }


        int sqrt = (int) Math.sqrt(50000);
        System.out.println(sqrt);
        for(int i = 1; i <= sqrt; i++) {
            int d = i*i;
            dp[d] = 1;

            for(int j = d+1; j < 50001; j++) {
                dp[j] = Math.min(dp[j], dp[j-d] + 1);
            }

        }

        System.out.println(dp[n]);

    }
}