μ•Œκ³ λ¦¬μ¦˜

[Java] BOJ 7626 Four Squares

🍊귀🍊 2024. 7. 31. 23:09

문제 

문제 링크 https://www.acmicpc.net/problem/17626

  • λΌκ·Έλž‘μ£ΌλŠ” 1770년에 λͺ¨λ“  μžμ—°μˆ˜λŠ” λ„· ν˜Ήμ€ κ·Έ μ΄ν•˜μ˜ 제곱수의 ν•©μœΌλ‘œ ν‘œν˜„ν•  수 μžˆλ‹€κ³  증λͺ…ν•˜μ˜€λ‹€.
  • μ–΄λ–€ μžμ—°μˆ˜λŠ” 볡수의 λ°©λ²•μœΌλ‘œ ν‘œν˜„λœλ‹€.
  • 예λ₯Ό λ“€λ©΄, 26은 52κ³Ό 12의 합이닀; λ˜ν•œ 42 + 32 + 12으둜 ν‘œν˜„ν•  μˆ˜λ„ μžˆλ‹€.
  • μ—­μ‚¬μ μœΌλ‘œ μ•”μ‚°μ˜ λͺ…μˆ˜λ“€μ—κ²Œ κ³΅ν†΅μ μœΌλ‘œ μ£Όμ–΄μ§€λŠ” λ¬Έμ œκ°€ λ°”λ‘œ μžμ—°μˆ˜λ₯Ό λ„· ν˜Ήμ€ κ·Έ μ΄ν•˜μ˜ 제곱수 ν•©μœΌλ‘œ λ‚˜νƒ€λ‚΄λΌλŠ” κ²ƒμ΄μ—ˆλ‹€.
  • 1900λ…„λŒ€ μ΄ˆλ°˜μ— ν•œ μ•”μ‚°κ°€κ°€ 15663 = 1252 + 62 + 12 + 12λΌλŠ” ν•΄λ₯Ό κ΅¬ν•˜λŠ”λ° 8μ΄ˆκ°€ κ±Έλ Έλ‹€λŠ” 보고가 μžˆλ‹€.
  • μ’€ 더 μ–΄λ €μš΄ λ¬Έμ œμ— λŒ€ν•΄μ„œλŠ” 56μ΄ˆκ°€ κ±Έλ Έλ‹€: 11339 = 1052 + 152 + 82 + 52.
  • μžμ—°μˆ˜ n이 μ£Όμ–΄μ§ˆ λ•Œ, n을 μ΅œμ†Œ 개수의 제곱수 ν•©μœΌλ‘œ ν‘œν˜„ν•˜λŠ” 컴퓨터 ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.
  • μž…λ ₯은 ν‘œμ€€μž…λ ₯을 μ‚¬μš©ν•œλ‹€. μž…λ ₯은 μžμ—°μˆ˜ n을 ν¬ν•¨ν•˜λŠ” ν•œ μ€„λ‘œ κ΅¬μ„±λœλ‹€. μ—¬κΈ°μ„œ, 1 ≤ n ≤ 50,000이닀.
  • 좜λ ₯은 ν‘œμ€€μΆœλ ₯을 μ‚¬μš©ν•œλ‹€. 합이 nκ³Ό κ°™κ²Œ λ˜λŠ” μ œκ³±μˆ˜λ“€μ˜ μ΅œμ†Œ 개수λ₯Ό ν•œ 쀄에 좜λ ₯ν•œλ‹€.

아이디어

  • n + 1 ν¬ν‚€μ˜ 배열을 제곱수의 개수λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•΄ μƒμ„±ν•œλ‹€.
  • 그리고 λ°°μ—΄μ˜ 1λΆ€ν„° nκΉŒμ§€ μ΄ˆκΈ°κ°’μ„ 본인의 수둜 μ €μž₯ν•œλ‹€. 
  • μ™œλƒν•˜λ©΄ 제일 큰 경우의 μˆ˜κ°€ 1의 제곱으둜 합을 λ‚˜νƒ€λ‚΄λŠ” 것이기 λ•Œλ¬Έμ΄λ‹€.
  • 그리고 이쀑 for문을 μ‚¬μš©ν•˜μ—¬ i번째 배열을 i번째 λ°°μ—΄μ˜ κ°’κ³Ό i - j * j 번째 λ°°μ—΄ 값에 1을 λ”ν•œ κ°’κ³Ό λΉ„κ΅ν•΄μ„œ 더 μž‘μ€ 값을 μ €μž₯ν•œλ‹€. 
  • μ œκ³±μˆ˜κ°€ κΈ°μ‘΄ μˆ«μžλ³΄λ‹€ 크면 μ•ˆλ˜λ―€λ‘œ j의 λ²”μœ„λŠ”  j * j κ°€ i보닀 μž‘μ„ λ•ŒκΉŒμ§€λ‘œ μ œν•œν•œλ‹€.

κ²ͺ은 μ‹œν–‰μ°©μ˜€

  • μ²˜μŒμ—λŠ” i번째 λ°°μ—΄μ˜ μˆ«μžκ°€ κ·œμΉ™μ„±μ΄ μžˆμ„κΉŒ μ‹Άμ–΄μ„œ μ—΄μ‹¬νžˆ μ°Ύμ•„λ΄€μ§€λ§Œ μ‹€νŒ¨ν•˜μ˜€κ³ ... 문제λ₯Ό 보자마자 λ– μ˜¬λ Έλ˜ 'λ°°μ—΄μ˜ 이전 값에 + 1을 ν•˜μ—¬ ν’€λ©΄λ˜μ§€ μ•Šμ„κΉŒ'λž€ 생각을 ν™œμš©ν•΄μ„œ ν’€μ—ˆλ‹€ 
  • κ·Όλž˜μ— ν’€μ—ˆλ˜ dp문제 μ€‘μ—μ„œ 제일 μ–΄λ ΅κ²Œ ν’€μ—ˆλ˜ 것 κ°™λ‹€ γ…œγ…œ

νž˜λ“  μ‹Έμ›€μ΄μ˜€λ‹€...

μ½”λ“œ

import java.io.*;
import java.util.*;

public class BOJ17626 {
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // μž…λ ₯κ°’
        int n = Integer.parseInt(br.readLine());

        // μ œκ³±κ°’μ˜ 개수λ₯Ό μ €μž₯ν•  λ°°μ—΄
        int arr[] = new int[n + 1];

        // λ°°μ—΄μ˜ i번째 값을 iκ°’μœΌλ‘œ μ €μž₯
        // μ΅œλŒ€ ν•„μš”ν•œ κ°œμˆ˜λŠ” 1의 제곱으둜 λ‹€ μ±„μš°λŠ” κ²½μš°μ΄λ―€λ‘œ
        for(int i = 1; i <= n; i++){
            arr[i] = i;
        }

        for(int i = 1; i <= n; i++){
            // μ œκ³±μˆ˜κ°€ 기쑴값보닀 크면 μ•ˆλ˜λ―€λ‘œ
            // j * j κ°€ i보닀 μž‘κ±°λ‚˜ κ°™μ„λ•ŒκΉŒμ§€ 반볡
            for(int j = 1; j * j <= i; j++){
                // i번째 λ°°μ—΄μ˜ 값을 i번째 λ°°μ—΄μ˜ κ°’κ³Ό
                // i번째 λ°°μ—΄μ—μ„œ j의 μ œκ³±κ°’μ„ λΊ€ κ°’μ—μ„œ 1 λ”ν•œκ°’ 쀑
                // 더 μž‘μ€ 값을 μ €μž₯
                arr[i] = Math.min(arr[i], arr[i - j * j] + 1);
            }
        }

        System.out.println(arr[n]);
    }
}