PS/BaekJoon

1932 JAVA μ •μˆ˜ μ‚Όκ°ν˜•

chaerlo127 2024. 2. 5. 01:07
728x90

 

 

1932번: μ •μˆ˜ μ‚Όκ°ν˜•

첫째 쀄에 μ‚Όκ°ν˜•μ˜ 크기 n(1 ≤ n ≤ 500)이 주어지고, λ‘˜μ§Έ 쀄뢀터 n+1번째 μ€„κΉŒμ§€ μ •μˆ˜ μ‚Όκ°ν˜•μ΄ 주어진닀.

www.acmicpc.net

πŸ€ 문제

        7
      3   8
    8   1   0
  2   7   4   4
4   5   2   6   5

μœ„ 그림은 크기가 5인 μ •μˆ˜ μ‚Όκ°ν˜•μ˜ ν•œ λͺ¨μŠ΅μ΄λ‹€.

맨 μœ„μΈ΅ 7λΆ€ν„° μ‹œμž‘ν•΄μ„œ μ•„λž˜μ— μžˆλŠ” 수 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜μ—¬ μ•„λž˜μΈ΅μœΌλ‘œ λ‚΄λ €μ˜¬ λ•Œ, μ΄μ œκΉŒμ§€ μ„ νƒλœ 수의 합이 μ΅œλŒ€κ°€ λ˜λŠ” 경둜λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ. μ•„λž˜μΈ΅μ— μžˆλŠ” μˆ˜λŠ” ν˜„μž¬ μΈ΅μ—μ„œ μ„ νƒλœ 수의 λŒ€κ°μ„  μ™Όμͺ½ λ˜λŠ” λŒ€κ°μ„  였λ₯Έμͺ½μ— μžˆλŠ” 것 μ€‘μ—μ„œλ§Œ 선택할 수 μžˆλ‹€.

μ‚Όκ°ν˜•μ˜ ν¬κΈ°λŠ” 1 이상 500 μ΄ν•˜μ΄λ‹€. μ‚Όκ°ν˜•μ„ 이루고 μžˆλŠ” 각 μˆ˜λŠ” λͺ¨λ‘ μ •μˆ˜μ΄λ©°, λ²”μœ„λŠ” 0 이상 9999 μ΄ν•˜μ΄λ‹€.

πŸ€ μž…λ ₯

첫째 쀄에 μ‚Όκ°ν˜•μ˜ 크기 n(1 ≤ n ≤ 500)이 주어지고, λ‘˜μ§Έ 쀄뢀터 n+1번째 μ€„κΉŒμ§€ μ •μˆ˜ μ‚Όκ°ν˜•μ΄ 주어진닀.

πŸ€ 좜λ ₯

첫째 쀄에 합이 μ΅œλŒ€κ°€ λ˜λŠ” κ²½λ‘œμ— μžˆλŠ” 수의 합을 좜λ ₯ν•œλ‹€.

πŸ€ 예제

예제 μž…λ ₯ 1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

예제 좜λ ₯ 1

30

μ½”λ“œ κ³Όμ •

μ ‘κ·Ό 방법

  1. μ‚Όκ°ν˜•μ˜ μ•„λž˜ λŒ€κ°μ„ μœΌλ‘œ 더해 μ΅œμ’… κ°€μž₯ 큰 값을 κ²°μ •ν•œλ‹€.
  2. μž…λ ₯ κ°’μ—μ„œ col(x)은 1이 μΆ”κ°€κ°€ 되고, row(y)λŠ” μ™Όμͺ½ λŒ€κ°μ„ κ³Ό 였λ₯Έμͺ½ λŒ€κ°μ„ μ΄ 각각 (y)와 (y+1) 이 λœλ‹€. 즉, μ €μž₯λ˜μ–΄ μžˆλŠ” 값이 자기 μžμ‹ μ˜ μœ„μΉ˜μ—μ„œ λ°”λ‘œ μ•„λž˜μ— μœ„μΉ˜ν•˜κ±°λ‚˜ κ·Έ μ•„λž˜μ—μ„œ μ˜†μœΌλ‘œ 1을 μ΄λ™ν•œ 것과 같은 것이닀.
  3. top-down 방식을 μ΄μš©ν•˜μ—¬ μ΅œμ’… 맨 μ•„λž˜ 행에 합을 μ €μž₯ν•˜μ—¬ κ°€μž₯ 큰 값을 λ‹΅μœΌλ‘œ μ„ μ •ν•œλ‹€.

ν‹€λ¦° μ½”λ“œ

for 문을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , recursion을 μ‚¬μš©ν–ˆλ‹€. for 문을 μ‚¬μš©ν–ˆλ‹€λ©΄ μ΅œλŒ€ μ‹œκ°„λ³΅μž‘λ„κ°€ O(n^2) 이기 λ•Œλ¬Έμ— μ‹œκ°„ μ΄ˆκ³Όκ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. ν•˜μ§€λ§Œ, recursion의 top-down λ°©μ‹μœΌλ‘œ μ§„ν–‰ν•˜κ²Œ λœλ‹€λ©΄ μ΅œλŒ€ μ‹œκ°„ λ³΅μž‘λ„λŠ” O(n!)둜 큰 값이 λ„μΆœλœλ‹€. n의 μ΅œλŒ€ 값은 500이기 λ•Œλ¬Έμ— μ΅œλŒ€ μ‹œκ°„ λ³΅μž‘λ„λŠ” 500!κ°€ λ˜λŠ” 것이닀. λ”°λΌμ„œ μ•„λž˜ μ½”λ“œλ‘œ 문제 접근은 μ‹œκ°„μ΄ˆκ³ΌλΌλŠ” κ²°κ³Όλ₯Ό μ΄ˆλž˜ν–ˆλ‹€.

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

public class Main{
    public static int[][] arr;
    public static int n;
    public static int max = 0;
    public static void main(String args[]) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        arr = new int[n][n];

        for(int i = 0; i < n ; i++){
            StringTokenizer st = new StringTokenizer(br.readLine());
            int index = 0;
            while(st.hasMoreTokens()){
                arr[i][index++] = Integer.parseInt(st.nextToken());
            }
        }

        // λ§μ…ˆ ν›„
        recurPlus(0, 0, 0);

        System.out.println(max);
    }

    public static void recurPlus(int col, int row, int num){
    	
        // 맨 μ•„λž˜μ— μœ„μΉ˜ν•œ 경우
        if(col == n){
            max = Math.max(max, num);
            return;
        }

        recurPlus(col + 1, row, arr[col][row] + num); // left
        recurPlus(col + 1, row + 1, arr[col][row] + num); // right
    }
}

λ§žμ€ μ½”λ“œ

λ”°λΌμ„œ, 이미 μ €μž₯λ˜μ–΄ μžˆλŠ” κ²½μš°μ—λŠ” λ”°λ‘œ 계산을 ν•˜μ§€ μ•ŠλŠ” DP(Dynamic Programming)을 μ΄μš©ν–ˆλ‹€. 방법은 top-down μ—μ„œ bottom-up λ°©μ‹μœΌλ‘œ λ³€κ²½ν–ˆμœΌλ©°, ν˜„μž¬ μœ„μΉ˜μ—μ„œ 계산이 μ•ˆλ˜μ–΄ μžˆλ‹€λ©΄ μ•„λž˜ 두 λŒ€κ°μ„ μ˜ κ²°κ³Ό κ°’μ—μ„œ ν˜„μž¬ μžμ‹ μ˜ 값을 λ”ν•œ 것이 더 큰 것을 μ €μž₯ν•œλ‹€.

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

public class Main{
    public static int[][] arr;
    public static int[][] dp;
    public static int n;
    public static void main(String args[]) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        arr = new int[n][n];
        dp = new int[n][n];

        for(int i = 0; i < n ; i++){
            StringTokenizer st = new StringTokenizer(br.readLine());
            int index = 0;
            while(st.hasMoreTokens()){
                arr[i][index++] = Integer.parseInt(st.nextToken());
            }
        }
        // bottom up 방식을 μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— λ§ˆμ§€λ§‰ 쀄에 μžˆλŠ” 수λ₯Ό 볡사
        for (int i = 0; i < n ; i++){
            dp[n-1][i] = arr[n-1][i];
        }

        System.out.println(recurPlus(0, 0));
    }


    public static int recurPlus(int col, int row){
    	// 맨 μ•„λž˜μ— μœ„μΉ˜ν•œ 경우 μžμ‹ μ˜ κ°’λ§Œμ„ return
        if(col == n - 1){
            return dp[col][row];
        }

        if(dp[col][row] == 0){
            dp[col][row] = Math.max(recurPlus(col + 1, row), recurPlus(col+1, row+1)) + arr[col][row];
        }

        return dp[col][row];
    }
}
728x90